web-dev-qa-db-ja.com

Ruby=)で[角括弧]メソッドを定義する方法は?

プログラミング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

[]メソッドの定義の仕組みがわかりませんか?

キーが[]の外側にあるのに、メソッドが呼び出されたときに[]の内側にあるのはなぜですか?

括弧なしでキーを使用できますか?

私はこれを書くためのはるかに良い方法があり、動作する独自のメソッドを書く方法を知っていますが、この[]メソッドは私を困惑させます...どんな助けも大歓迎です、ありがとう

42
oFca

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" 
37
Gazler

ただの構文糖です。メッセージ送信に変換される特定の構文パターンがあります。特に

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)
46
Jörg W Mittag

角括弧は、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

同じことが/*-などで機能します。

8
jigfox

これは演算子オーバーローダーであり、定義したクラス内のメソッドの動作、または動作を変更するクラスの動作をオーバーライドまたは補完します。 []とは異なる他の演算子に対して行うことができます。この場合、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
0
codeSeeker