🍒 はじめに
チェリー本輪読会の第6週目のエントリーになります。
輪読会の概要については第1週目にまとめています。
🍒 輪読会 第6週目まとめ
第4章4.9.1〜第5章5.3.2まで
期間:2021年06月28日〜2021年07月02日
さまざまな繰り返し処理
Rubyには、同じことを繰り返す方法がいくつかあります。
timesメソッド
繰り返しの回数が決まっているときはtimesメソッドがおすすめです。
timesメソッドは、イテレータとも呼ばれます。イテレータ「繰り返す(iterate) + もの(-or)」という意味です。Ruby 用語としては、もっぱら繰り返し処理のためのブロック付きメソッドのことを指します。
Integer#times (Ruby 3.0.0 リファレンスマニュアル)
Ruby 用語としては、もっぱら繰り返し処理のためのブロック付きメソッドのことを指す。
uptoメソッド、downtoメソッド
Integer#upto (Ruby 3.0.0 リファレンスマニュアル)
Integer#downto (Ruby 3.0.0 リファレンスマニュアル)
stepメソッド
開始値.step(上限値, 1度に増減する大きさ)
Numericとは「数、数的な、数に関するの意」
Numeric#step (Ruby 3.0.0 リファレンスマニュアル)
while文
while文は指定した条件が「真」である間、処理を繰り返します。
while 条件式 (真であれば実行) 繰り返したい処理 end
until文
while文の反対で、条件が「偽」である間、処理を繰り返します。
until 条件式 (偽であれば実行) 繰り返したい処理 end
for文
eachメソッド、mapメソッドで代用できるためほとんど出番のない構文です。
普段、輪読会メンバーもfor文を使っている人はいませんでした。
for文はメソッドではありません。Rubyの書き方のひとつです。
for 変数 in 配列やハッシュ 繰り返し処理 end
loopメソッド
無限ループを作りたいときは、loopメソッドが使えます。
loop do 無限ループ用の処理 end
例えば、puts foo
と記述すると、無限に'foo'がputsされ続け大変なことになります。
そんな時、繰り返し処理を途中で抜ける方法があります。
break
繰り返し処理を中断し、繰り返しの中から抜けることができるnext
繰り返し処理を中断し、次の回の繰り返し処理へ移動することできるreturn
繰り返し処理を中断し、メソッドから抜け出すことができる
逆に、繰り返し処理をやり直したい場合は以下を使います。
redo
同じ条件で繰り返し処理をやり直す
繰り返し処理用の制御構造
繰り返し処理の途中で、処理を中断したり、次の回に飛ばしたり処理を制御したいときがあります。そのような処理を制御するための構造がRubyでは用意されています。以下のキーワードで処理を制御することが可能です。
break
- breakを使ってloop処理を抜けます。
- 下記は、 変数
m
がfujiwara
と同一になった場合、breakさせます。(繰り返し処理を脱出します) - 下記の例では、loopメソッドを使っていますが、for文やeachメソッドなど他の繰り返し記法でも利用できます。
- 下記は、 変数
irb(main):073:1* def choose_members irb(main):074:1* members = ['fujiwara', 'masukawa', 'naoi', 'masu'] irb(main):075:2* loop do irb(main):076:2* m = members.sample irb(main):077:2* puts m irb(main):078:2* break if m == 'fujiwara' irb(main):079:1* end irb(main):080:1* puts 'I am a composer!!' irb(main):081:0> end => :choose_members irb(main):082:0> choose_members masukawa naoi masukawa fujiwara I am a composer!! => nil
next
- nextを使って次の処理へ移動してみます。
-
next if m == 'fujiwara'
がtrueとなった場合、次の繰り返し処理へ移動します。
-
irb(main):031:1* def check_main_songwriter irb(main):032:2* ['fujiwara', 'masukawa', 'naoi', 'masu'].each do |m| irb(main):033:2* next if m == 'fujiwara' irb(main):034:2* puts "#{m}さんは、違います" irb(main):035:1* end irb(main):036:2* ['作詞', '作曲'].each do |n| irb(main):037:2* puts "fujiwaraさんは、#{n}します" irb(main):038:1* end irb(main):039:0> end => :check_main_songwriter irb(main):040:0> check_main_songwriter masukawaさんは、違います naoiさんは、違います masuさんは、違います fujiwaraさんは、作詞します fujiwaraさんは、作曲します => ["作詞", "作曲"]
breakとreturnの違い
breakは、上記の例で取り上げたように「繰り返し処理からの脱出」を行うために利用する記法です。
returnは、「メソッドからの脱出」を行うために利用されます。メソッドの実行を終了するとも言い換えられます。
- returnを使ってメソッドから脱出させます。
- 下記は、 変数
m
がfujiwara
と同一になった場合、returnさせます。(メソッドを脱出します) - 下記の例では、loopメソッドを使っていますが、for文やeachメソッドなど他の繰り返し記法でも利用できます。
return if m == 'fujiwara'
がtrueになった場合、メソッドから脱出します。メソッド内で記述しているputs 'I am a composer!!'
は、実行されません。
- 下記は、 変数
irb(main):083:1* def choose_members irb(main):084:1* members = ['fujiwara', 'masukawa', 'naoi', 'masu'] irb(main):085:2* loop do irb(main):086:2* m = members.sample irb(main):087:2* puts m irb(main):088:2* return if m == 'fujiwara' irb(main):089:1* end irb(main):090:1* puts 'I am a composer!!' irb(main):091:0> end => :choose_members irb(main):092:0> choose_members masukawa masukawa naoi masu fujiwara => nil
throw と catch を使った大域脱出
breakでは、繰り返し処理を中断し、一番内側の処理しか脱出できませんが、throw
とcatch
を使えば、一気に外側のループまで脱出できます。(returnのようにメソッドの脱出ではありません。あくまでもループ全体の脱出になります)
:bump
がタグ文字といってcatchとthrowの後に記述します。同じタグ文字にする必要があります。
irb(main):095:0> records = [ 'LAMP', 'ダイヤモンド', '天体観測' ] => ["LAMP", "ダイヤモンド", "天体観測"] irb(main):096:0> release = [1, 2, 3] => [1, 2, 3] irb(main):097:1* catch :bump do irb(main):098:2* records.shuffle.each do |record| irb(main):099:3* release.shuffle.each do |n| irb(main):100:3* puts "#{record}は、#{n}枚目のシングルです}" irb(main):101:4* if record == '天体観測' && n == 3 irb(main):102:4* throw :bump irb(main):103:3* end irb(main):104:2* end irb(main):105:1* end irb(main):106:0> end ダイヤモンドは、1枚目のシングルです} ダイヤモンドは、2枚目のシングルです} ダイヤモンドは、3枚目のシングルです} LAMPは、3枚目のシングルです} LAMPは、2枚目のシングルです} LAMPは、1枚目のシングルです} 天体観測は、2枚目のシングルです} 天体観測は、1枚目のシングルです} 天体観測は、3枚目のシングルです} *=> nil*
ハッシュ
ハッシュは、「キー」と「値」のセットでデータを管理するオブジェクトのことです。
他の言語では「連想配列」「辞書」「マップ」と呼ばれたりします。
英語のHashは、コマ切れ肉と野菜を炒めた料理の事を指し、ハッシュドビーフの語源でもあります。
ハッシュの3つの書き方
ハッシュロケット⇒
を使った書き方。キーは文字列です。
{ 'first_single' => 'LAMP', 'second_sigle' => 'ダイヤモンド', 'third_single' => '天体観測' }
ハッシュロケット⇒
を使った書き方。キーはシンボルです。
{ :first_single => 'LAMP', :second_sigle => 'ダイヤモンド', :third_single => '天体観測' }
ハッシュロケット⇒
を省略した書き方。キーはシンボルですが、:
コロンの位置が右側に変わります。
{ first_single: 'LAMP', second_sigle: 'ダイヤモンド', third_single: '天体観測' }
ちなみに、改行して書くこともできます。
{ 'first_single' => 'LAMP', 'second_sigle' => 'ダイヤモンド', 'third_single' => '天体観測' }
シンボル
シンボルは任意の文字列と一対一に対応するオブジェクトです。Rubyがメソッドなどの名前を識別するためのラベルをオブジェクトにしたものです。先頭に:
をつけて表現します。
文字列との違いは、主に4つあります。
- クラスが違います。文字列はStringクラスです。シンボルはSymbolクラスです。
# 文字列 irb#1(main):014:0> 'BumpOfChicken'.class => String # シンボル irb#1(main):015:0> :BumpObChicken.class => Symbol
- 同じシンボルは同じオブジェクトIDです。文字列は毎度オブジェクトIDが変わります。
# 文字列(毎回、違う) irb#1(main):016:0> 'BumpOfChicken'.object_id => 260 irb#1(main):017:0> 'BumpOfChicken'.object_id => 280 irb#1(main):018:0> 'BumpOfChicken'.object_id => 300 # シンボル(毎回、同一になる) irb#1(main):019:0> :BumpOfChicken.object_id => 2296228 irb#1(main):020:0> :BumpOfChicken.object_id => 2296228 irb#1(main):021:0> :BumpOfChicken.object_id => 2296228
- シンボルは整数として扱われるため、文字列より高速に処理できます。
- 同じシンボルであれば同じオブジェクトである理由で、シンボルの方がメモリ効率がよいです。
- シンボルは、ソース上では文字列のように見え、内部では整数として扱われる、両者を仲立ちするような存在です。整数として扱えることが高速に処理できる理由です。class Symbol (Ruby 3.0.0 リファレンスマニュアル)
- シンボルはイミュータブル(非破壊的)なオブジェクトです。
- 文字列はミュータブル(破壊的)なオブジェクトのため変更は可能ですが、シンボルはイミュータブルなため変更できません。勝手に変更されては困る名前などの用途に向いています。
# 文字列は変更が可能です。 irb(main):002:0> name = 'bump' => "bump" irb(main):003:0> name.upcase! => "BUMP" # シンボルは変更できません。 irb(main):004:0> name = :bump => :bump irb(main):005:0> name.upcase! (irb):5:in `<main>': undefined method `upcase!' for :bump:Symbol (NoMethodError)
irbの情報を確認
irb_info
コマンドで、irbの情報を確認することができます。
shiro@shiro:~$ irb irb(main):001:0> irb_info => Ruby version: 3.0.0 IRB version: irb 1.3.6 (2021-06-19) InputMethod: ReidlineInputMethod with Reline 0.2.6 RUBY_PLATFORM: x86_64-darwin19
irbで、行を挿入する方法
option
+ Enter
で、実行中のirbに行を挿入することができます。
とても便利で頻繁に使っています。
GitHub内をアドバンスドサーチ
advanced search とは、高度検索と訳せます。複数の検索パラメータを組み合わせることによって、指定された範囲でより正確な結果を得ることのできる機能です。
Googleなどが有名ですが、GitHubにも存在することを教えてもらいました。
メソッドの使い方、記法など、希望する条件を入力し検索することができます。
GitHub · Where software is built
コントリビュートチャンス
チェリー本を読み進めていたとき、ふと英単語の誤植が目に入ってきました。
139頁の真ん中あたりのサンプルコード内で、
本来numbers
の綴りが正しいはずですが、nunmbers
となっていました。
nunmbersのループは脱出するが、fruitsのループは継続する
コントリビュートというと大げさではありますが、人生初めての誤植発見というのもあり、嬉しくてテンション上がりました。笑
その後、すぐにフィヨルドブートキャンプ内のバグ・誤字脱字の窓口へ報告を行いました。
なんと直接、著者の伊藤さんにご対応いただき、無事に技術評論社の正誤表へ反映いただきました。
スタンプ
そんなこともあり、輪読会メンバーの(id:yana_g)さんが「コントリビュートチャンス」スタンプを作ってくれました笑。こういった遊び心とても素敵ですね。
絵文字ジェネレーター - Slack 向け絵文字を無料で簡単生成
参考書籍
- 伊藤淳一 著/『プロを目指す人のためのRuby入門 言語仕様からテスト駆動開発・デバッグ技法まで』/技術評論社/2017年https://gihyo.jp/book/2017/978-4-7741-9397-7
- 五十嵐邦明,松岡浩平 著/『ゼロからわかる Ruby 超入門』/技術評論社/2018年https://gihyo.jp/book/2018/978-4-297-10123-7
- 高橋征義、後藤裕蔵 著/『たのしいRuby第6版』/SBクリエイティブ/2019年https://tanoshiiruby.github.io/6/index.html
- プログラミング言語 Ruby リファレンスマニュアル https://docs.ruby-lang.org/ja/
🍒 まとめ
今週で6週目を終えました。
始めた当初は苦手意識のあった「irb」と「るりま」ですが、日々使用することで親しみが増し、今ではだいぶ仲良くなれたと思います。わからないことに出くわしたときは、すぐに「るりま」を参照する習慣が身につきました。また「irb」を使用し手元で動きを確認することも、今では自然と手がスッと動くようになり、身についてきたと思います。
輪読会を通して、この大きな2つの武器を手に入れられたことは大きな収穫です。
引き続き、この武器を活用し技術を磨いていきたいと思います。
では、また来週!(次回、第7週目)