## 3/16 Rubyの真偽値はfalseまたはnil以外はすべてtrue:Ruby固有の特徴 if文の戻り値を変数に代入できる:greeting = if country == 'japan' elsif...のように書ける メソッド名はスネークケースで書く:hello_world のような形式 %記法でエスケープが不要になる:%!unkoburi!のように囲える ヒアドキュメント:<<-識別子 テキスト 識別子 の形式で複数行の文章を格納できる。式展開も使える。 <<-を途中で使うとインデントされる。引数として渡すこともできる。ヒアドキュメントを二つ使うと配列を作れる(これすごい便利じゃないか?) 配列の結合:[10,20,30].join で全部くっつく unless:ifの逆 でもこれ逆に頭がこんがらがりそう ==true , ==false は冗長なので使わない:それはそうだ case文:絶対に使うべき局面でもなぜか忘却してif文を使ってしまう message = case xxx when 'yyy' end のように使う 三項演算子:絶対に使うべき局面なのになぜか忘却して以下略 式 ? 真だった場合の処理 : 偽だった場合の処理 のように使う メソッドにデフォルト値の引数を付ける:def greet(country = 'japan')などで引数なしでjapanが引数として扱われる。(x, y=x)のようにするとyが無指定の場合にxと同じ値として扱われる !で終わるメソッドは破壊的メソッドだが、ついていないからといって破壊的ではないとは限らない:concatは付いていないが破壊的 エンドレスメソッド定義 endがいらない:def greet = 'hello!' lengthとsizeはどちらも”まったく”同じメソッド:なにか違うはずだろと思っていたのに…… 標準ライブラリと組み込みライブラリはイコールではない:同じだと思ってた putsとprintの差は改行の有無だが、pはオブジェクトそのものがメソッドの戻り値になる(p 123の後に123を参照すると123が戻ってくる、putsの場合はnil)、ppはpよりも整形してきれいに出力してくれる。pはオブジェクトをStringではなくinspectに変換している 配列で元の大きい添字を指定すると間の値はnilで埋められる:a=[1,2,3] a[4]=50などとすると[1,2,3,nil,50]となる 配列はa << 2 などで最後に要素を追加できる:コードを見た覚えがある割には自分で使ったことはなかった 削除はdelete.at(n)で行う。delete(n)だとnに一致する要素がまとめて削除される divmodというメソッドは商と余りを配列で返す 14.divmod(3)は[4,2]になる delete_ifメソッドを使うとdo |x|で条件を別に記述できる Rubyプログラマはfor文を使わない:確かに例文でほとんど出てこないので気にかかっていた。たまたまかと思いきや本当に使わないのか 配列の要素を順番に取り出す作業はeachメソッド、要素をどう扱うかはブロック(ブロックの中身に書くコード)の役割:ごっちゃになっていたのでようやく納得した 変数名の重複により他のものが参照できなくなることをシャドーイングという do endの代わりに{}でブロックをくくることもできる:僕が最初にうまく理解できなかった理由はこれだな .mapを使うとブロックの戻り値が配列の要素となる新しい配列が作成される:new = numbers.map { |n| n * 10}で配列numbersを10倍にした新しい配列が作れる 112ページまで ## 3/17 numbers.select {|n| n.even?} : このようにselectメソッドを使うと条件を満たした配列のみを作成できる。この例では偶数のみの配列が生成される numbers.find : findメソッドは戻り値が真になった最初の値のみを返す numbers.sum : 名前通り配列の要素を合計できる。文字列でも使える('')単純な連結ならjoinメソッドの方が楽だがsumは文字列の加工に優れる &:メソッド名でシンプルに書ける:ブロックパラメータが1つ、ブロックの中のメソッドに引数がない、メソッドを1回呼び出す以外の処理がない、といった条件をすべて満たすと [1,2,3,4,5,6].select{|n| n.odd?}を[1,2,3,4,5,6,].select{&:odd?}のように簡潔に書ける。演算子を使っている場合は不可能 (1..5)←これはRangeという名前のオブジェクトだった!:ただのそういう感じの簡略記法かと思っていた。点が三つだと5は含まれなくなる (1..5).to_aで値が連続する配列を作ることができる:これ””””答え””””だ。こういうものがあるといいと思ってた RBG変換器の実装を通じて:これたぶんもっと短くなる方法ありそうだな……と思っていたらすぐ下でsumを使った記法が書かれていた。ぜひものにしたい 123ページまで ## 3/19 to_intsメソッドのリファクタリングを通じて:空の配列を用意して、ほかの配列をループ処理した結果を空の配列に詰め込んでいくような処理の大半はmapメソッドに置き換えることができる……らしい 上級編に書かれていた多重代入➜scanメソッド➜mapメソッドを呼ぶからの&シンボ➜エンドレスメソッドの流れはカードバトのフィニッシのコンボみがある a.values_at(0,2,4)この形式で取得したい要素を複数指定できる。 a[a.size - 1]この形式で最後の要素を取得できる a[-1]これでもいける a.lastこれもいける a[開始地点,範囲] = 置き換える数字 で要素を置き換えられる a.concat(b)でaを破壊的にbと結合する(bは破壊されない) e, *f = 100,200,300このような書き方をするとはみ出した数字を含めた配列がfに代入される e, * = 100,200,300 この場合は100のみがeに格納されて他は無視される e, = 100,200,300 これも同じ a, *b, c, d = 1,2,3,4,5 この場合は間に挟まれた残りの要素がbに入る(2,3) 配列を配列にpushで代入する場合、スプラット演算子をつけなければ多重配列になる 上記の特性を活かしてwhen節で配列を複数の条件として展開できる 上記の特性を活かして簡潔な形で配列を連結させることもできる[-1, 0, *a, 4, 5] %w記法:これはフォーマッタが教えてくれた。%W大文字を使うとタブ文字なども使える 'Ruby'.chars この形式で文字を一文字ずつ分解して配列にできる 'Ruby,Java,Python'.split(',') 文字列から配列を作る a = Array.new(5, 0) 配列に初期値を設定して作る方法。この例では5つの0が配列に入る a = Array.new(10) {|n| n % 3 + 1} ブロックを使った初期値の設定例。引数の数だけ呼ばれてブロックの中身が要素の添字になる 第2引数デフォルト値を指定するとすべての配列が同じ文字列オブジェクトを参照するため、破壊的メソッドですべてが置き換わる ミュータブルとイミュータブル:イミュータブルなオブジェクトは破壊的変更の影響を受けない。主に数値、シンボル、真偽値、nil、Rangeはイミュータブル freezeメソッドを使うとイミュータブルなオブジェクトにすることができる with_indexはeach以外でも使えるmapやdelete_ifなど : Enumeratorクラスに属するものはwith_indexを呼び出せる 配列の要素分だけブロックパラメータを用意すると各要素の値が別々の変数に格納される ブロックパラメータを丸括弧で囲うとwith_indexなどで他のブロックが必要になる場合でも上記の挙動を実現できる 番号指定パラメータ:_1 このような形式でブロックに格納する変数を指定できる do..endの代わりに使う{}は結合度が高い:異なった解釈をする場合があるのでブロックに丸括弧が必須 しかしながらdo..endと{}は基本的には同じなのでendの後ろにドットをつけて.joinなどをつけても機能する 151ページまで ## 3/20 始点を持たない範囲オブジェクト:(10..) これで10以上を表す。そんなことできるんだ。逆も可能 numbers[2..]などで3番目以降の要素を取得する (nil..nil)で全範囲オブジェクトを作成可能 timesメソッド 5.times {|n| sum += n} などのように使う:知っているはずなのにこれまで使う機会がなかった 1ずつ増減させながら処理したい場合はupto/downtoメソッドが便利: 10upto(14) {|n| a << n} のような形式で1ずつ14まで増える配列が作れる 一定の数を増減させる場合はstepメソッドを使う : 1.step(10,2) {|n| a << n} これで2ずつ10未満まで増える while文 while 真である条件 処理 endで書く:Rubyだと影が薄い気がする。逆バージョンのuntil文もある for文 使わないけど一応ある: for n in numbers sum+= n endのように書く eachとの違いはローカル変数がforの外でも使えるところ 意図的に無限ループを作る:loop do 処理 end throwとcatch: これRubyでもあるんだ……と思っていたが他の言語のthrowとは意味が違っていた。breakの強化バージョンとして使う。catch :tag do ループ処理1 ループ処理2 throw :tag endで内側から一気に外側まで抜ける breakとreturnの違い:breakは繰り返し処理からの脱出だが、returnはメソッドからの脱出になる redo 繰り返し処理をやり直す:RPGの質問みたいなことができる countで制限回数を指定できる エイリアスメソッドがたくさんある理由:他の言語との整合性、直感性、あとからもっといい名前をつけた、英語との一体感 ここから第五章 ハッシュとはキーと値の組み合わせでデータを管理するオブジェクト:他の言語では連想配列やディクショナリ、マップと呼ばれている { キー1 => 値1, キー2 => 値2} ハッシュリテラルとブロックの見分け方:ロケットでキーと値が区切られている(ハッシュ)、ブロックパラメータがある(ブロック)、処理が書かれている(ブロック) ハッシュの利点:大量の値が格納されていても指定したキーに対応する値を高速に取り出せる ハッシュの比較:並び順が違っていてもキーと値の対応が同じであればtrue ハッシュのeachメソッド:ブロックパラメータを1つにするとキーと値が配列に順番に格納される シンボル:他の言語ではあまり見られない特徴らしい。コロンの後に続いて文字列を書くとシンボルリテラルを作ることができる。 シンボルの利点:文字列をよく似ているが整数として扱われるので文字列よりも高速に処理できる シンボルの利点2:同じシンボルは同じオブジェクトとして扱われる。なので大量の同じシンボルは文字列よりもメモリの効率に優れる。 シンボルの利点3:シンボルはイミュータブルなオブジェクトなので破壊的変更ができない シンボルの用途:ハッシュのキーに用いる。文字列よりも高速に値を取り出せる。キーは文字列である必要性がないのでよく使われる。 シンボルの用途2:可読性の向上。特定の数値で任意の状態を表すと計算効率はいいが可読性が悪い。シンボルを使うと効率をあまり犠牲にせずに可読性を高められる シンボルの利用でロケットを省略する:{japan => 'yen'}このように書くものを{japan: 'yen'}こうして書ける。圧倒的に記述量が減る。 両方ともシンボルにする: {japan: :yen} かなり使われているらしい ハッシュのキーはそれぞれ別のデータ型でも問題ないが推奨はされない。一方で値の方はよく混在する(例:人物目録を作る際は名前が文字列、歳が数値、人間関係が配列、電話番号がハッシュなどになったりする) キーワード引数:buy_burger(menu, drink: true, potato: true) end シンボルと似たような形式で可読性の高い引数を設定できる アスタリスク二個でハッシュの変数を指定すると中身をキーワード引数として利用できる メソッド定義側のキーボード引数はシンボルっぽいだけであってシンボルではない:しかし呼び出す側はれっきとしたシンボルである(紛らわしすぎる) ハッシュで使われるメソッド色々:keys(キーを配列として返す)、values(ハッシュの値を配列として返す)、has_key?(読んで字のごとく) 定義されていないキーワードを同時に受け取るにはアスタリスク2個の引数を最後に用意する 189ページまで