学習記録 (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メソッド: オブジェクトと同一の結果を配列で返す 引数の中に正規表現が入る場合は//で囲む
キャプチャしたものを出力するには`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
d
をs
に変えると文字列が表示できる。
- テストファイルの記述方法 変数を使っている
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
を使うことができる。
<残りの課題>
- シンボリックリンク
- ls -lのシンボリックリンクの情報はシンボリックリンクそのものの情報、File.lstat相当
- File.statではシンボリックリンクはリンク先のファイル同等に扱われる。ftypeの表示も
file
となる - 1行目の
tolal
: 消費ブロック数 ls -sで確認できる .blocksメソッド 割り当てられているブロック数 - 拡張ファイル属性 ls- l@で表示
- パーミッションの後ろの
.``+
への対応
.(ドット) 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 = 3
とb = 4
となる- a , b = [3,4] もまた
a = 3
とb = 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
- テストしやすいコードしにくいコード 純粋な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メソッド : 配列の要素数を数える、引数で数える要素を指定
- Minitestは