普段仕事で使っているRuby on Railsですが、ソースコードを読む機会もなかなかないので、試しにやってみることにしました
読めるようにするまで
以前書いた記事で読めるようにするまでの設定を画像キャプチャ付きで解説しましたので、よろしければこちらをご参照下さい
shitake4.hatenablog.com
読んだ箇所
in?
を今日は読んでみようと思います
どんな使い方だっけ?
読んでみる前にまずは使い方を調べてみます
RAILS GUIDESの日本語ドキュメントを見てみると
述語in?は、あるオブジェクトが他のオブジェクトに含まれているかどうかをテストします。渡された引数がinclude?に応答しない場合はArgumentError例外が発生します。
in?の例を示します。
1.in?([1,2]) # => true "lo".in?("hello") # => true 25.in?(30..50) # => false 1.in?(1) # => ArgumentError
ソースコードを読んでみる
1. railsプロジェクトのactivesupportにある機能ですので、activesupportディレクトリのlib配下で def in?
を探してみます
2. 該当箇所が1箇所あったので、みてみます
1. activesupport > lib > active_support > core_ext > object > inclusion.rb
class Object # Returns true if this object is included in the argument. Argument must be # any object which responds to +#include?+. Usage: # # characters = ["Konata", "Kagami", "Tsukasa"] # "Konata".in?(characters) # => true # # This will throw an +ArgumentError+ if the argument doesn't respond # to +#include?+. def in?(another_object) another_object.include?(self) rescue NoMethodError raise ArgumentError.new("The parameter passed to #in? must respond to #include?") end 省略 end
引数(another_object)に対してinclude?
を実行しています
include?
を調べてみます
array.include?(obj)
include?メソッドは、配列の要素に引数objが含まれていればtrue、なければfalseを返します。要素と引数objが同じかどうかの比較には==メソッドが使われます。
animals = ["dog", "cat", "mouse"] puts animals.include?("cat") puts animals.include?("elephant")true false
str.include?(other_str)
include?メソッドは、文字列の中に引数other_strの文字列が含まれるかどうかを調べます。含まれるときはtrue、含まれないときはfalseを返します。
s = "Supercalifragilisticexpialidocious" puts s.include?("exp")true
mod.include?(other_mod)
include?メソッドは、クラスやモジュールが引数のモジュールother_modをインクルードしているかどうかを調べます。インクルードしていればtrueを、そうでなければfalseを返します。
親クラスがインクルードしているモジュールを指定してもtrueになります。
p String.include?(Comparable) p String.include?(Enumerable) p String.include?(Kernel)true true (Ruby 1.9ではfalse) true
rubyのinclude?の実装は3つあるみたいです(String, Array, Module)
another_object.include?(self)
は引数のオブジェクトがレシーバに対してinclude?かどうかをチェックしています
そして、メソッドが実装されていない場合には、 ArgumentError
を返すという処理になっていました
rescue NoMethodError raise ArgumentError.new("The parameter passed to #in? must respond to #include?") end
読んでみて
include?
はよく使用していますが、in?はあまり馴染みがなかったので、挙動を学べたので、うまく使い分けなど出来るといいなと思います