プログラミングRuby-実用的なプログラマーガイド を経て、このコードにつまずきました:
class SongList
def [](key)
if key.kind_of?(Integer)
return @songs[key]
else
for i in [email protected]
return @songs[i] if key == @songs[i].name
end
end
return nil
end
end
[]メソッドの定義の仕組みがわかりませんか?
キーが[]の外側にあるのに、メソッドが呼び出されたときに[]の内側にあるのはなぜですか?
括弧なしでキーを使用できますか?
私はこれを書くためのはるかに良い方法があり、動作する独自のメソッドを書く方法を知っていますが、この[]メソッドは私を困惑させます...どんな助けも大歓迎です、ありがとう
Rubyのメソッドは、多くの言語とは異なり、いくつかの特殊文字を含むことができます。その1つは配列検索構文です。
独自のハッシュクラスを実装して、ハッシュ内のアイテムを取得するときに、それを元に戻したい場合は、次の操作を実行できます。
class SillyHash < Hash
def [](key)
super.reverse
end
end
これを証明するには、次のようにハッシュを呼び出します。
a = {:foo => "bar"}
=> {:foo=>"bar"}
a.[](:foo)
=> "bar"
a.send(:[], :foo)
=> "bar"
したがって、def []は、my_array["key"]
あなたには奇妙に見えるかもしれない他のメソッドは次のとおりです。
class SillyHash < Hash
def [](key)
super.reverse
end
def []=(key, value)
#do something
end
def some_value=(value)
#do something
end
def is_valid?(value)
#some boolean expression
end
end
明確にするために、[]
メソッドは配列またはハッシュとは無関係です。次の(想定された)例を見てください。
class B
def []
"foo"
end
end
B.new[]
=> "foo"
ただの構文糖です。メッセージ送信に変換される特定の構文パターンがあります。特に
a + b
と同じです
a.+(b)
==
、!=
、<
、>
、<=
、>=
、<=>
、===
、&
、|
、*
、/
、-
、%
、**
、>>
、<<
、!==
、=~
、および!~
も同様です。
また、
!a
と同じです
a.!
~
にも同じことが当てはまります。
次に、
+a
と同じです
a.+@
-
にも同じことが当てはまります。
プラス、
a.(b)
と同じです
a.call(b)
セッター用の特別な構文もあります。
a.foo = b
と同じです
a.foo=(b)
最後に重要なことですが、インデックス作成には特別な構文があります。
a[b]
と同じです
a.[](b)
そして
a[b] = c
と同じです
a.[]=(b, c)
角括弧は、Array#size
のようなメソッド名であり、メソッドとしてArray#[]
があり、他のメソッドと同様に使用することもできます。
array = [ 'a', 'b', 'c']
array.[](0) #=> 'a'
array.[] 1 #=> 'b'
array[2] #=> 'c'
最後のものは構文糖のようなもので、最初のものとまったく同じです。 Array#+
は同様に機能します:
array1 = [ 'a', 'b' ]
array2 = [ 'c', 'd' ]
array1.+(array2) #=> [ 'a', 'b', 'c', 'd' ]
array1.+ array2 #=> [ 'a', 'b', 'c', 'd' ]
array1 + array2 #=> [ 'a', 'b', 'c', 'd' ]
次のような数字を追加することもできます。
1.+(1) #=> 2
1.+ 1 #=> 2
1 + 1 #=> 2
同じことが/
、*
、-
などで機能します。
これは演算子オーバーローダーであり、定義したクラス内のメソッドの動作、または動作を変更するクラスの動作をオーバーライドまたは補完します。 []とは異なる他の演算子に対して行うことができます。この場合、SongListクラスのインスタンスで[]が呼び出されたときの[]の動作を変更しています。
Songlist = SongList.newがあり、songlist ["foobar"]を実行すると、カスタム定義が動作し、「foobar」がパラメーター(キー)として渡され、「foobar」 「メソッドが言うことは何でもキーに対して行われるべきです。
試して
class Overruler
def [] (input)
if input.instance_of?(String)
puts "string"
else
puts "not string"
end
end
end
foo = Overruler.new
foo["bar"].inspect
foo[1].inspect