How does the Ruby chain work?

Why can you link this:

"Test".upcase.reverse.next.swapcase

but not this:

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

Where

class My_Class 

  def a 
    @b = 1 
  end 

  def b
    @b = @b + 2 
  end 

  def c 
    @b = @b -72 
  end

end
+5
source share
3 answers

Methods upcase, reverse, nextand swapcasereturn objects String, and all of these methods are suitable for ... you guessed it, Stringobjects!

When you call a method (most often, for example 99.9999% of the time), it returns an object. This object has methods defined on it that can then be called, which explains why you can do this:

"Test".upcase.reverse.next.swapcase

You can even call reverseas many times as you want:

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

That's because it returns the same type of object, object String!

But you cannot do this with yours MyClass:

x = My_Class.new

x.a.b.c

a , b, . , , MyClass . , a , :

def a
  @b += 2
  self
end

, b self, c MyClass. , c , . self, . Schrödinger cat. , .

+7

:

"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>'
+6

The last expression in a function is its implicit return value. You need to return selfif you want to bind similar methods.

For example, your method ais currently returning 1. bnot a number method. You want to change it like this:

def a 
  @b = 1 
  self
end 
+5
source

All Articles