Ruby 用方法链认识自我

Ruby 用方法链认识自我,ruby,methods,self,Ruby,Methods,Self,我想用Ruby来理解self 在下面粘贴的代码中,如果我使用 fox=动物。新名称(“狐狸”)。颜色(“红色”)。自然栖息地(“森林”)。物种(“哺乳动物”) 然后打电话 fox.to_s 如果我没有在每种方法中返回self,那么它不会起任何作用 为什么我在每种方法中都需要自我?创建新动物后,变量是否已保存? class Animal def name(name) @name = name self end def specie(specie) @specie

我想用Ruby来理解self

在下面粘贴的代码中,如果我使用

fox=动物。新名称(“狐狸”)。颜色(“红色”)。自然栖息地(“森林”)。物种(“哺乳动物”)

然后打电话

fox.to_s

如果我没有在每种方法中返回self,那么它不会起任何作用

为什么我在每种方法中都需要自我?创建新动物后,变量是否已保存?

class Animal
  def name(name)
    @name = name
    self
  end
  def specie(specie)
    @specie = specie
    self 
  end
  def color(color)
    @color = color
    self 
  end
  def natural_habitat(natural_habitat)
    @natural_habitat = natural_habitat
    self 
  end
  def to_s
    "Name: #{@name}, Specie: #{@specie}, Color: #{@color}, Natural Habitat: #{@natural_habitat}"
  end
    end

在您的示例中,使用
self
作为返回值比较方便。这些方法返回实例本身,以便您可以调用:

fox = Animal.new
fox.name("Fox").color("red").natural_habitat("forest").specie("mammal")

fox.name(“fox”)
的值是实例本身,这就是为什么可以在其上调用
.color(“red”)

这种模式在Ruby中很少使用,它在Java和JavaScript等语言中更为常见,在jQuery中尤其盛行。部分原因是您在这里描述的冗长,其次是Ruby以
attr\u访问器
attr\u编写器
的形式提供了一个方便的变异生成器

这些存取/变异双重用途方法的一个问题是模糊性。您拥有的实现不完整,无法从中读取。您需要的是:

def color(*color)
  case (color.length)
  when 1
    @color = color
    self
  when 0
    @color
  else
    raise ArgumentError, "wrong number of arguments (%d for 0)" % color.length
  end
end
这需要大量代码来实现一些东西,可以通过两种方式使用:

animal.color('red')
animal_color = animal.color
如果你想使用这些工具,你需要编写你自己的元编程方法来生成它们,尽管我不鼓励你这么做。使用
attr\u访问器
方法和选项散列

下面是等效的Ruby模式:

# Up-front assignment via Hash
animal = Animal.new(
  name: 'Fox',
  color: 'red',
  natural_habitat: 'forest',
  specie: 'mammal'
)

# Assignment after the fact
animal.color = 'white'
如果在不调用self的情况下实现#name方法,如下所示:

def name(name)
  @name = name
end
调用此方法时将返回一个字符串

Animal.new.name #=> returns "name of animal"
这意味着

Animal.new.name.specie

将对字符串对象调用#specie方法(这可能会引发NotImplemented错误),而不是对实现该方法的Animal类对象进行调用。

如果希望使用链式方法/fluent接口,则需要从每次方法调用中返回该对象。否则,您不能对方法调用结果调用其他方法。@mudasobwa我不是说它返回一个新实例,我是说它返回实例本身,即本例中的
fox
本身。