学習記録 (2/17 -24 )

2/17

  • ls -lコマンドのパーミッションの後ろにつく記号

    (スペース) 通常のUnixのアクセス権限だけが有効 .(ドット) SELinuxのアクセス権限が付いている +(プラス) その他のアセス権限が付いている。例えば、sambaで公開しているファイルにWindows上で権限設定したりすると付く。

  • @はmac拡張属性を表す

  • file.statオブジェクトのパーミッション取得と進数変換

(rdbg) p a.mode    # command
=> 16877
(rdbg) p a.mode.to_s(8)    # command
=> "40755"
(rdbg) puts "0%o" % a.mode     # ruby
040755
nil
(rdbg) puts a.mode.to_s(8)    # ruby
40755
nil
(rdbg) printf  "0%o\n" , a.mode     # ruby
040755
nil

#進数%oの前に0を入れることで0が左にはいる
  • printf:書式を指定して出力。戻り値はnil
('商品情報: カテゴリー %s 型番 %d', 'bag', 10111)
#[実行結果]
商品情報: カテゴリー bag 型番 10111
  • 桁数を右揃えで指定 : printf("%5s","abc") 左揃え : printf("%-5s","abc")
#数値型の桁数を指定する場合も、文字数を指定する場合同様です。

puts "12345"
printf("%5d",123)
#[実行結果]
12345
  123 

#数値型の場合は、空白に0を詰めて表示できます。

puts "12345"
printf("%05d",123)
#[実行結果]
12345
00123
#このように、5桁に対して足りない部分は0で補われています。
  • springf(戻り値のみ): printfメソッドがコンソールに対して直接出力するのに対して、sprintfメソッドは文字配列に対して出力するためのメソッドになります。

printfとは 与えられた引数を指定フォーマットの文字列として出力します。 似たような名前のsprintfは「文字列として返す」のに対して、今回のprintfは「文字列として出力(表示)する」点が異なります

2/18

<正規表現>

  • \dは任意の半角数字1文字 \dは\wに含まれる
  • \wは英単語を構成する文字+アンダースコア [a-zA-Z0-9_]
  • \d{2,5} : 半角数字が2-5文字
  • [AZ] : AまたはZ、またはの間になんの仕切りもなく並んでいるので連続している文字列に見えるのに注意
  • [A-Z] : AまたはBまたは...またはZ
  • [-AZ]、[AZ-] : -またはAまたはZ
  • 正規表現を使うときには//で囲む
  • [-AZ]? : -またはAまたはZ または無し
  • (-AZ)? : 文字列'-AZ' または無し
  • . : 任意の1文字
  • + : 直前の文字が1文字以上
  • * : 0文字以上 .* =任意の文字0文字以上
  • \Aは文字列の始まり、\zは文字列の終わりを意味する
  • ^: 以外の ^A*=`A以外の任意の文字
  • ^: 行頭
  • ?: 最短マッチ *?/.?/+? 貪欲さを消す
  • $ : 行末 ^ +$ = 行末まで半角スペースが続く文字列、改行文字は含まれないので行末に\nを指定することもできる。
  • \t:タブを表すメタ文字
  • \s: 半角、タブ空白文字全般 \s = [ \t\r\n\f]
    • Rubyの場合は半角スペース( )、タブ文字(\t)
    • 改行文字(\n)、復帰文字(\r)、改ページ文字(\f)
    • かっこで囲って |でつなぐ ^.+heroku\/(api|scheduler).+$



  • scanメソッド: オブジェクトと同一の結果を配列で返す 引数の中に正規表現が入る場合は//で囲む

  • grepメソッド(配列ー配列) :配列.grep(オブジェクト) 正規表現に対してはパターンにマッチした要素を返す

  • キャプチャしたものを出力するには`gsub(検索文字列、キャプチャ()入り,'\1, \2')

mの中に3つのマッチデータが格納されていてハッシュと同じ方法で取得できる。

p m 
=> #<MatchData "2016-05-08" year:"2016" month:"05" day:"08">

次のような形も可能

s = '2016-05-08'
if /(?<year>\d+)-(?<month>\d+)-(?<day>\d+)/ =~ s
  # 名前付きキャプチャがそのままローカル変数になる
  puts "year: #{year}, month: #{month}, day: #{day}"
  # => year: 2016, month: 05, day: 08
end

理論演算子=~ : 正規表現オブジェクト =~ string

2/19

  • lsコマンドの揃えはそれぞれの列の再材の

  • 左揃え

a = 7
printf("%0#{a}d",123)
printf("%#{a}d",123)
#=> 0000123    123

dsに変えると文字列が表示できる。


  • テストファイルの記述方法 変数を使っている
  def test_score1
    marks = '6,3,9,0,0,3,8,2,7,3,X,9,1,8,0,X,6,4,5'
    assert_equal 139, calculate_score(marks)
  end


users = []
users << User.new('Alice','Ruby',20)
users << User.new('Bob','Python',30)

p users    # command
=> [#<User:0x00000001116147e0 @age=20, @first_name="Alice", @last_name="Ruby">, #<User:0x0000000111614718 @age=30, @first_name="Bob", @last_name="Python">]

p users[0]    # command
=> #<User:0x00000001116147e0 @age=20, @first_name="Alice", @last_name="Ruby">
  • クラスの中にメソッドを作って初めてそのインスタンスにメソッドを適用できる。

  • initializeはデフォルトでprivateで外部から呼び出せない

  • セッターがインスタンス変数に直接代入される時だけattr_accessorを使うことができる。

<残りの課題>


.(ドット) SELinuxのアクセス権限が付いている +(プラス) その他のアセス権限が付いている。例えば、sambaで公開しているファイルにWindows上で権限設定したりすると付く


ディレクトリにスティッキービットを付与: $ chmod +t free_dir ファイルにもw権限があるユーザーに対しファイル削除を制限(ファイル所有者以外)

taku-no-MacBook-Pro:lib takunaka$ ls -l@
total 48
-rw-r--r--@ 1 takunaka  staff   310 Feb 18 13:31 class.rb
    com.apple.metadata:_kMDItemUserTags   42 
-rw-r--r--@ 1 takunaka  staff   160 Feb 15 15:01 filestat.txt
    com.apple.metadata:_kMDItemUserTags   42 
-rw-r--r--  1 takunaka  staff  1472 Feb 18 14:00 ls4.rb
-rw-r--r--@ 1 takunaka  staff  2891 Feb 18 17:55 ls5.rb
    com.apple.metadata:_kMDItemUserTags   42 
-rw-r--r--@ 1 takunaka  staff    81 Feb 18 12:54 printf
    com.apple.metadata:_kMDItemUserTags   42 
-rw-r--r--@ 1 takunaka  staff   342 Feb 18 16:34 regexp.rb
    com.apple.metadata:_kMDItemUserTags   42 
taku-no-MacBook-Pro:lib takunaka$ ls -l
total 48
drwxr-xr-x  2 takunaka  staff    64 Feb 16 14:32 00
-rw-r--r--@ 1 takunaka  staff   310 Feb 18 13:31 class.rb
-rw-r--r--@ 1 takunaka  staff   160 Feb 15 15:01 filestat.txt
-rw-r--r--  1 takunaka  staff  1472 Feb 18 14:00 ls4.rb
-rw-r--r--@ 1 takunaka  staff  2891 Feb 18 17:55 ls5.rb
-rw-r--r--@ 1 takunaka  staff    81 Feb 18 12:54 printf
-rw-r--r--@ 1 takunaka  staff   342 Feb 18 16:34 regexp.rb


  • メソッドの表記法 '#' : クラスの中のインスタンスメソッド String#to_i '.'あるいは'::' : クラスメソッド File.exist?(File::exist?)


2/20

メソッド分割

  • lsコマンド 時刻で並べ替え -tオプション

  • DateTimeクラス : requre'date'が必要。現在時刻DateTime.now

require "date"

d1 = Date.today
d2 = Date.new(2007, 3 ,14)

print("本日の日付:", d1, "¥n")
print("3日後の日付:", d1 + 3, "¥n")
print("5日前の日付:", d1 - 5, "¥n")
print("2ヶ月後の日付:", d1 >> 2, "¥n")
print("6ヶ月前の日付:", d1 << 6, "¥n")
print("本日の日付と2007/03/14との差は", d1 - d2, "日です¥n")


  • Arrayクラスメソッド : Array(3)3つの空配列の入った配列を作る array = Array.new(3){"Red"}それぞれの配列にブロック内の処理を行う

  • 配列を作るとき、[ ]の代わりに%w( )、%i( )を使う

  • レビューの指摘

    • 配列を配列を作る場合mapを使う
    • 配列の中にn個の空配列を作る : [[]] * n
    • if-elseを分割
    • メソッドはまとめてファイルの最初の方に定義する

printf("",,,) : ""の中に文字列(式展開を含む)を入力し、そのあとのカンマに%部分に入る値を入力していく


  • クラス/メソッド/変数関連
    • インスタンス変数 : クラスの中に定義されていても、クラスメソッドからはアクセスできない(インスタンスからのみ)
    • クラスインスタンス変数(イニシャライズの外で定義したインスタンス変数): クラスメソッドからアクセスできるが、インスタンスメソッドからはアクセスできない。
    • クラス変数 : クラスの中の変数でアクセスすることでインスタンスの中の変数の値も変化する。
    • クラス名::クラス定数で外部からクラス定数にアクセスできる
    • インスタンスメソッドはクラス内のメソッドの中でしか呼び出せない、クラスメソッド、クラス内では呼び出せない
    • クラスインスタンス変数はクラスの中のインスタンスメソッド以外の範囲で参照できる、クラスメソッドからもアクセス可能
    • クラス変数はそのどちらからもアクセス可能


  • git コミット修正メソッド
    • git reset --soft HEAD^ : コミットを戻す(ステージのまま)
    • git reset HEAD : ステージを戻す
    • git amend : コミットメッセージを取り消す
    • git revert : コミットを打ち消す新たなコミット


  • 以下のようなコードを書いて、他のメソッドの初期に実行するとinitializeメソッドのような動きをする。(@が必要) (後記:ハッシュでもよし)
  def dataspace(files)
    @nlink_space = files.map { |file| file.nlink.size }.max + 1
    @uid_space = files.map { |file| file.uid.size }.max + 1
    @gid_space = files.map { |file| file.gid.size }.max + 2
    @size_space = files.map { |file| file.size.size }.max + 2
  end

2/21

< TOPIC >

  • divmod : 商と余を返す。14.divmod(3) => [4,2]
  • a, b = 3 ,4[3,4]を返しa = 3b = 4となる
  • a , b = [3,4] もまたa = 3b = 4となる
  • 配列に*をつけるとその場でflattenできる
  • 代入自体が戻り値を持つのでif分の条件に使うことができる
  • レシーバーがnilであっても&.を使うとnilを返す、no methodエラーにならない。
  • limit ||=10 limitがnilかfalseであったなら、10を代入する
  • nilガード先の変数を begin/endで囲い複数行の記述ができる
  • あえてinitializeをせずに手動初期化のメソッドを作りそこに||=を入れることで重い初期化を回避できる
  • 例外処理 rescue => e 文字列(エラー名)が変数eに代入されている。
begin
  1 / 0
rescue => e
  puts "何か問題が発生しました。"
  p e
end
puts 
  • rescueの後にエラーのクラスを指定することでそのエラーだけrescueする
begin
  1 / 0
rescue ZeroDivisionError
  puts "対象の例外やー。"
end

< TOPIC >

  • mapで出力する配列をflatにするにはflat_mapを使用する
  • ブロック内でfalse/nilの値は返さないfilter_map
  • concatで配列を結合すれば、最後にflattenしなくて済む
  • カウンタつき繰り返し処理、 _with_indexに引数()をつけるとその値からカウントが始まる
  • each_with_object オブジェクトを作って出力する -if __FILE__ == $0という分岐は、スクリプトが実行されているパスとソースファイルが同じであるという意味。  この分岐のついたメソッドは、require先のファイルでは実行されない __FILE__とは”現在のソースファイル名”の意味 $0現在実行中のスクリプトの名前を表す文字列 $PROGRAM_NAMEも同義

  • getoptsメソッドでのオプションの取得

    • オプションはoptions = ARGV.getopts('a','r','l')の形で取れる optionにはハッシュで{'a'=>ture,'r'=>false,'l'=true}のような形で出力される
    • 引数をつける(オプションが 'a'から'a:'になる)とハッシュの値が引数の値になる
#!/usr/bin/env ruby
require 'optparse'

options = ARGV.getopts('a:')
puts options
% ./arg.rb -a 111
{"a"=>"111"}


p /abc/ =~ "abc"          # 0
p /abc/ =~ "pabc"         # 1
p /abc/ =~ "ppabc"        # 2
p /abc/ =~ "ppabcppabc"   # 2
p /abc/ =~ "pab"          # nil


  • initializeなしのattr_accessor : 外部から入力する。イニシャライズ時に値を入れなくもいい。
class Cat
 attr_accessor : name

 def cat_name
  "#self.name"
  end
end

に対し

cat1 = Cat.new
cat1.name = 'たま'
cat1.cat_name #=> たま
  • 可長変引数

    • *をつけた引数は制限がなく配列として認識される、ローカル変数として渡される方は*をつけない
def variadic(arg1, arg2, *others)
  p arg1
  p arg2
  p others
end

variadic(1,2,3,4,5)
  # 1
  # 2
  # [3, 4, 5]
variadic(1,2)
  # 1
  # 2
  # []


  • **引数 引数をキーワードと値にすることで、ハッシュに格納される。
def keyword_args(**keywords)
  puts keywords
end

keyword_args(a:1,b:2)
#=> {:a=>1, :b=>2}

引数にキーワードと値が代入される


< TOPIC >

  • max_number = [max_number , a].max をeachで回すと回すと配列の最大数が得られる
  • 組み合わせは素直にMODE_TABLEを使う (8進数から2進数に変換する必要がない)


wcコマンドについて

  • 行数と単語数とバイト数、ファイル名を表示
  • 複数ファイルを指定した時には改行し結果を返し、最後の行にトータルを表示

  • コマンドラインの引数を取得 ARGVは引数の入った配列を表す

  • 標準入力 : IOオブジェクト 組込定数STDIN/グロバル変数$stdin

  • 標準出力 : IOオブジェクト 組込定数STDOUT/グロバル変数$stdin
  • 標準エラー出力 : STDERR/ $stderr
  • tty?メソッド、コンソールに関連づけられている場合、tty?trueになる

  • getsは標準入力を受け取る。$stdinオブジェクトが省略されている。

  • 文字列のバイト数の取得は.bytesize
  • gets/readline : 標準入力を「文字列」として取得
  • readlines : 最後の改行まで全てを「配列」として取得
  • read : 最後の行まで全てを[文字列]として取得
  • getsはブロックの入力も標準入力として受け取る。
File.open("data001.txt"){|f|
  p f.gets  # 1行目
  p f.gets  # 2行目
  p f.gets  # 3行目
}

getsは読み込めない行はnilを返すが、readlineはEOFErrorを返す

  • readlineはファイルの中身の文字列を読んでいる。
  • 引数に複数のファイルが指定されている場合はその中身を直接繋げて読み込んでいる。

2/24

- Pathnameクラス Pathnameオブジェクトはパス名を示す

  • テストしやすいコードしにくいコード 純粋なrubyコードはテストしやすい -> libに入れる ターミナルの情報(画面の幅など)はテストコードに反映しにくい ->binに入れて分ける
  • rubocop.ymlでrubocopを使用する対象ディレクトリをコントロールする
  • クラスの中でインスタンス変数を使わなくても、ハッシュを使ってもよい
  • ”文字列に+で順次入れ込んでいく”ではなく、”文字列を配列に入れんんで最後のjoinする”というロジックがより良い
  • %i[]ではハッシュを作る
  • 配列は*で展開
  • formatメソッドの実例
 `format('%<mon>2d %<mday>2d %<hour>02d:%<min>02d', mon: mtime.mon, mday: mtime.mday, hour: mtime.hour, min: mtime.min)`
  • テストの作成
    • Minitestはtest_で始まるメソッドを探して実行する
    • test_`で始まるメソッドは複数定義するvことができる
    • assert_equal a, b (a == bであればパス)
    • assert a (aが真であればパス)
    • refute b (bが偽であればパス)
    • assert_output : 標準出力の内容を検証する -linesメソッド(Stringクラス) : 文字列の改行までを要素にした配列を返す -countメソッド : 配列の要素数を数える、引数で数える要素を指定