5

なぜこれを連鎖させることができますか:

"Test".upcase.reverse.next.swapcase

しかし、これではありません:

x = My_Class.new 
x.a.b.c

どこ

class My_Class 

  def a 
    @b = 1 
  end 

  def b
    @b = @b + 2 
  end 

  def c 
    @b = @b -72 
  end

end
4

3 に答える 3

7

upcase、およびメソッドはすべてオブジェクトを返します。これらのメソッドはすべてreverse、... お察しのとおり、オブジェクトです。nextswapcaseStringString

メソッドを呼び出すと (多くの場合、99.9999% の確率で)、オブジェクトが返されます。このオブジェクトにはメソッドが定義されており、これを呼び出すことができる理由が説明されています。

"Test".upcase.reverse.next.swapcase

reverse何度でも呼び出すことができます:

"Test".reverse.reverse.reverse.reverse.reverse.reverse.reverse.reverse

すべては、同じ種類のオブジェクト、オブジェクトを返すためStringです!

しかし、あなたはあなたのでこれを行うことはできませんMyClass:

x = My_Class.new

x.a.b.c

それが機能するには、メソッドはメソッドが定義されaたオブジェクトを返す必要があります。b現時点では、 のインスタンスだけMyClassがそれを持っているようです。これを機能させるにはa、次のように、オブジェクト自体の戻り値を作成できます。

def a
  @b += 2
  self
end

これを推定すると、メソッドはクラスのインスタンスでのみ使用できるため、メソッドbも返す必要があります。この例で何が返されるかは重要ではありません。これがチェーンの最後だからです。戻ることができましたが、できませんでした。シュレディンガーの法。箱を開けるまでは誰にもわかりません。selfcMyClasscself

于 2011-02-03T01:25:02.190 に答える
6

他の回答のサポートとして、このコードは次のとおりです。

"Test".upcase.reverse.next.swapcase

...ほぼ同じです...

a = "Test"
b = a.upcase
c = b.reverse
d = c.next
e = d.swapcase

....上記のコードには中間結果を指す余分な変数が残っているのに対し、元のコードには余分な参照が残っていないことを除いて。あなたのコードでこれを行う場合:

x = MyClass.new   # x is an instance of MyClass
y = x.a           # y is 1, the last expression in the a method
z = y.b           # Error: Fixnums have no method named 'b'

Ruby 1.9のtap方法を使用すると、これをより明確にすることもできます。

irb> "Test".upcase.tap{|o| p o}.reverse.tap{|o| p o}.next.tap{|o| p o}.swapcase
#=> "TEST"
#=> "TSET"
#=> "TSEU"
=> "tseu"

irb> class MyClass
irb>   def a
irb>     @b = 1
irb>   end
irb>   def b
irb>     @b += 2
irb>   end
irb> end
=> nil

irb(main):011:0> x = MyClass.new
=> #<MyClass:0x000001010202e0>

irb> x.a.tap{|o| p o}.b.tap{|o| p o}.c
#=> 1
NoMethodError: undefined method `b' for 1:Fixnum
from (irb):12
from /usr/local/bin/irb:12:in `<main>'
于 2011-02-03T01:58:02.487 に答える
5

関数の最後の式は、その暗黙の戻り値です。selfそのようなメソッドをチェーンしたい場合は、戻る必要があります。

たとえば、aメソッドは現在を返してい1ます。 b数字の方法ではありません。次のように変更する必要があります。

def a 
  @b = 1 
  self
end 
于 2011-02-03T01:19:29.633 に答える