Ruby цепочечный метод / массив - PullRequest
3 голосов
/ 31 июля 2010

Как мне реализовать '<<', чтобы иметь такое же поведение при использовании в качестве цепного метода? </p>

class Test
  attr_accessor :internal_array

  def initialize
    @internal_array = []
  end

  def <<(item)
    @internal_array << :a
    @internal_array << item
  end
end

t = Test.new
t << 1
t << 2
t << 3
#t.internal_array => [:a, 1, :a, 2, :a, 3]
puts "#{t.internal_array}" # => a1a2a3

t = Test.new
t << 1 << 2 << 3
#t.internal_array => [:a, 1, 2, 3]
puts "#{t.internal_array}" # => a123 , Why not a1a2a3?

Я хочу, чтобы оба случая дали один и тот же результат.

Ответы [ 2 ]

4 голосов
/ 31 июля 2010

Добавьте self в качестве последней строки в методе <<, чтобы вернуть его.Таким образом, вы неявно возвращаете массив, а не экземпляр. </p>

0 голосов
/ 31 июля 2010

Объяснение ответа выше:

Когда метод связан, следующий метод применяется к результату первого метода.

Например:

class A
  def method1
    B.new
  end
end

class B
  def method2
    C.new
  end
end

class C
  def method3
    puts "It is working!!!"
  end
end

Код ниже будет работать

A.new.method1.method2.method3

, но это не будет

A.new.method1.method3.method2

, поскольку экземпляркласс B, который является результатом A.new.method1, не реализует method3.Это то же самое из:

(((A.new).method1).method3).method2

Код, использованный в вопросе выше, был немного более хитрым, потому что и у Test, и у Array был метод <<.Но я хочу, чтобы Test # << возвращал себя, а не тот @internal_array, который был возвращен. </p>

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...