🍒 はじめに
チェリー本輪読会の第12週目のエントリーになります。
輪読会の概要については第1週目にまとめています。
- 第1週目のエントリーはこちら
- 第2週目のエントリーはこちら
- 第3週目のエントリーはこちら
- 第4週目のエントリーはこちら
- 第5週目のエントリーはこちら
- 第6週目のエントリーはこちら
- 第7週目のエントリーはこちら
- 第8週目のエントリーはこちら
- 第9週目のエントリーはこちら
- 第10週目のエントリーはこちら
- 第11週目のエントリーはこちら
🍒 輪読会 第12週目まとめ
第7章7.10.1〜第7章7.11まで
期間:2021年08月09日〜2021年08月13日
第8章にも少し入りましたが、こちらは次週へまとめます。
エイリアスメソッドの定義
alias 新しい名前 元の名前
エイリアスメソッドを定義する場合は、事前に元のメソッドを定義しておく必要があります。
class Numbergirl def introduce "福岡市博多区から参りましたナンバーガールです” end alias greeting introduce end numbergirl = Numbergirl.new numbergirl.introduce => "福岡市博多区から参りましたナンバーガールです" numbergirl.greeting => "福岡市博多区から参りましたナンバーガールです"
クラス/メソッドの定義 (Ruby 3.0.0 リファレンスマニュアル)
メソッドの削除
undef 削除するメソッドの名前
メソッドの定義をあとから削除することができます。
先程の、Numbergirl
クラスを継承し、その後定義しておいたintroduce
メソッドを削除してみます。
class Zazenboys < Numbergirl undef introduce end zazenboys = Zazenboys.new zazenboys.intoroduce : undefined method `intoroduce' for #<Zazenboys:0x00007fa552839290> (NoMethodError)
クラス/メソッドの定義 (Ruby 3.0.0 リファレンスマニュアル)
ネスト(入れ子)したクラスの定義
class 外側のクラス class 内側のクラス end end
クラスの内部に定義したクラスは、::
を使って参照できます。
外側のクラス::内側のクラス
この形を、名前空間(ネームスペース)と呼びます。(通常はクラスよりモジュールが使われることが多いです。)
class Numbergirl class Zazenboys attr_reader :menber def initialize(member) @member = member end end end leader = Numbergirl::Zazenboys.new('向井秀徳') leader => #<Numbergirl::Zazenboys:0x00007fa556873d88 @member="向井秀徳">
等値を判断するメソッドや演算子4つ
equal?
英語の意味そのままなので分かりやすいです。等しければtrueを返します。
object_idを比較しているので、代入している内容が文字列だとfalseになります。object_idが違うためです。
numbergirl = 'Band' zazenboys = 'Band' hakata = numbergirl numbergirl.equal?(zazenboys) => false numbergirl.equal?(hakata) => true
==
オブジェクトの内容が等しいか判断します。
100 == 100.000 => true 'a' == 'a' => true 'a' == 'A' => false 'a' == :a => false foo = 'hoge' => "hoge" bar = 'h'+ 'o' + 'g' + 'e' => "hoge" foo == bar => true
eql?
==
とは別に、値が同じどうかを判定することができます。
==
との違いは、ハッシュ値が等しいかどうかで判断する点です。
hashメソッドで、ハッシュ値を確認し同じであれば、trueになります。
numbergirl = 'Band' zazenboys = 'Band' numbergirl.hash => 1476835131188092417 zazenboys.hash => 1476835131188092417 numbergirl.eql?(zazenboys) => true
Hash#hash (Ruby 3.0 リファレンスマニュアル)
===
左辺が単独のStringやIntegerオブジェクトの場合は、==
と同じように判断されます。
左辺がClassオブジェクトの場合は、右辺がそのクラスのインスタンスであるかどうかを判断します。
左辺が正規表現の場合は、=~
と同じようにマッチしたかどうかを判断します。=~ を使って正規表現を比較する
100 === 100.00 => true 'a' === 'A' => false 'a' === 'a' => true /\w{6}-\d{3}/ === 'MONGOL-800' => true
また、case文のwhen節の内部で行われている処理ですが、===
で判断されています。
# case文の公式 case 比較したいオブジェクト when A # 処理 when B # 処理 else # 処理 end # 内部で行われている処理 if A === 比較したいオブジェクト # 処理 elsif B === 比較したいオブジェクト # 処理 else # 処理 end
case 'foo' when 'foo' puts 'true' when /w{3}/ puts 'true' else puts 'false' end # true => nil case 100 when 'foo' puts 'true' when /w{3}/ puts 'true' else puts 'false' end # false => nil
オープンクラス
Rubyはクラスの継承に制限がありません。String や Integer といった基本的なクラス(組み込みクラス)も自由に改変できます。定義済みのクラスへ、メソッドを追加することも上書きすることも可能です。Rubyのクラスは変更に対してオープンなので、「オープンクラス」と呼ばれています。
以下、Arrayクラスを継承させた独自のクラスになります。
class Numbergirl < Array end band = Numbergirl.new() => [] band << '向井秀徳' => ["向井秀徳"] band << '田渕ひさ子' => ["向井秀徳", "田渕ひさ子"] band => ["向井秀徳", "田渕ひさ子"] band.class => Numbergirl # 継承しないとエラーになる。 class Numbergirl end band = Numbergirl.new() => #<Numbergirl:0x00007f84d916b420> band << '向井秀徳' : undefined method `<<' for #<Numbergirl:0x00007f84d916b420> (NoMethodError)
モンキーパッチ
組み込みクラスやメソッドを追加したり変更したりします。このように自分が期待する挙動へ変更することを、モンキーパッチといいます。
class Numbergirl def initialize(name) @name = name end def introduce "#{@name}です" end end band = Numbergirl.new('ナンバーガール') band.introduce => "ナンバーガールです" # モンキーパッチを当てて、希望する挙動へ変更する。 class Numbergirl def introduce "福岡市博多区から参りました#{@name}です" end end band.introduce => "福岡市博多区から参りましたナンバーガールです"
原則として、オープンクラス、モンキーパッチには頼らない
オープンクラス、モンキーパッチは非常に強力です。誤って使用してしまうとプログラム全体に不具合を生じさせてしまう原因となってしまいます。
原則として、まずはオープンクラス、モンキーパッチに頼らずにプログラムが書けないか考える必要があります。
大いなる力には、大いなる責任が伴うことを忘れてはいけない。 Matz
特異メソッド (singleton メソッド)
Rubyはすべてがオブジェクトなので、StringクラスやArrayクラスもオブジェクトです。そして、それらのクラスは、Classクラス
のインスタンスになります。
class String end String.class => Class class Foo end Foo.class => Class
特異メソッドとは、特定のオブジェクトに紐づくメソッドのことです。 オブジェクト固有のメソッドのことで、あるオブジェクトにはあるメソッドが存在しますが、同じクラスの別のオブジェクトには存在しません。
特異メソッドはdef オブジェクト名.メソッド名
で定義できます。
class Instance def i_method puts 'インスタンスメソッドです。' end end foo = Instance.new bar = Instance.new # 特異メソッドを定義します。 def foo.s_method puts '特異メソッドです。' end foo.i_method => インスタンスメソッドです。 bar.i_method => インスタンスメソッドです。 # オブジェクトがfooで、特異メソッドとしてs_methodを定義しているので呼び出せる。 # s_methodは、fooのみが持つ特異メソッドとして定義されている。 foo.s_method => 特異メソッドです。 # オブジェクトがbarと異なるため呼び出せない。(barオブジェクトにはs_methodは定義していない) bar.s_method : undefined method `s_method' for #<Instance:0x00007f8474a980d0> (NoMethodError)
るりまを参照する際には、クラスメソッドではなく、特異メソッドと書かれているので置き換えて読みます。
Ruby におけるクラスメソッドというのは Class クラスのインスタンスの特異メソッドを便宜上クラスメソッドと呼んでいて、実態は特異メソッドの一種です。
ダックタイピング
という言葉に由来するプログラミング用語です。
オブジェクトのクラスが何であろうと、そのメソッドが呼び出せればOKとするプログラミングスタイルのことです。オブジェクトを特徴づけるのは、実際のクラスや継承関係ではなく、そのオブジェクトがどのように振る舞うか?(どんなメソッドを持っているか?)です。
class Member def play puts 'メンバーは楽器を演奏する' end end class Guitar < Member def play puts 'ギターを演奏する' end end class Bass < Member def play puts 'ベースを演奏する' end end member = Guitar.new member.play # => ギターを演奏する member = Bass.new member.play # => ベースを演奏する
同じ名前のメソッドが複数のオブジェクトに属することをオブジェクト指向の用語で、「ポリモーフィズム」といいます。playメソッドの実行結果はそれぞれ違います。(putsの中身が違う)
ポリモーフィズム
- 共通メインルーチンを作るための仕組み。
- 呼び出す側のロジックを一本化する仕組み。
- 呼び出される側の引数や戻り値の形式を統一する必要がある。
botが導入されました
今週、楽しみにしていたbotが輪読会へ導入されました〜!
botとは?
choosing-someone-discord-bot(Discordのボイスチャンネルに参加しているメンバーをランダムに指名するbot)
Discordの音声チャンネルで開催されている輪読会ですが、毎回、司会やドライバーなどを決める作業がありました。その都度irb
を開きsampleメソッドをまわして決めていたのですが、多少の手間と煩わしさがありました。そこで、この作業をbotで代替する目的で、トミーさんが開発されていたのが今回紹介するbotになります。今までの手間がなくなり、かつエンタメ性もプラスされ、楽しく、便利になりました!
botの詳細は、トミーさん(id:eatplaynap329)のブログ、GitHubページに詳しく書かれています。
mitaka.rbへ初参加!
輪読会メンバーの紹介で初めてmitaka.rbへ参加しました。
イベント管理アプリをモブプロで作る会でした。
Webアプリケーションの制作過程を、モブプロ形式で見ることができました。テスト駆動開発(TDD)の流れをベースに、どのように思考しコードを書いてくのか?熟練者のプログラマの手元をLIVEで見ることができ勉強になりました。Vimを使っている画面も初めて見ることができました。他にも、esaを初めて使ってみたり、いろいろ経験できよかったです。
そしてなにより、主催の@tatsuoSakurai さんや、@okuramasafumi さんがとても優しく親切で、とても雰囲気の良いコミュニティでした。ぜひまた参加したいと思います!
参考書籍
- 伊藤淳一 著/『プロを目指す人のための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/
- 小餅良介 著/ 『独習Ruby on Rails』https://www.shoeisha.co.jp/book/detail/9784798160689
- 平澤章 著/『オブジェクト指向でなぜつくるのか 第3版 』https://www.nikkeibp.co.jp/atclpubmkt/book/21/S00180/
🍒 まとめ
チェリー本、最初の難関であるクラスの章が完了しました!
いや〜、大変でした。しかしその分、同時に参加した『オブジェクト指向でなぜつくるのか』輪読会ともあわせて、クラス、オブジェクト指向の基礎について学ぶことができた章でした。 今までは、「クラス怖い」「継承?クラスメソッド?」と、自信の持てなかった内容ですが、輪読会を通して理解することができ大きな自信となりました。次回は、モジュールに入ります!
では、また来週!(次回、第13週目)