用equals定义Ruby中的方法

时间:2012-10-10 04:19:45

标签: ruby syntax

对Ruby不熟悉,我无法向自己解释 Ruby中方法定义的行为。

下面举例说明......

class Foo
  def do_something(action)
    action.inspect
  end
  def do_something_else=action 
    action.inspect
  end
end

?> f.do_something("drive")
=> "\"drive\""

?> f.do_something_else=("drive")
=> "drive"

第一个例子是自我解释。我试图理解的是第二个例子的行为。除了看起来是一个产生字符串文字,而另一个不是,实际发生了什么?为什么我会使用一个而不是另一个?

4 个答案:

答案 0 :(得分:14)

通常,do_something是吸气剂,do_something=是定位器。

class Foo
  attr_accessor :bar
end

相当于

class Foo
  def bar
    @bar
  end

  def bar=(value)
    @bar = value
  end
end

要回答有关行为差异的问题,以=结尾的方法始终返回表达式的右侧。在这种情况下,返回action,而不是action.inspect

class Foo
  def do_something=(action)
    "stop"
  end
end

?> f = Foo.new
?> f.do_something=("drive")
=> "drive"

答案 1 :(得分:10)

实际上正在定义两个方法,并将称为方法。 Ruby中的很多东西都可以定义为方法,甚至是+-*/等运算符。 Ruby允许方法有三个特殊的符号后缀。我自己完成了这个短语。 符号后缀的含义是,方法末尾的内容将指示该方法假设的工作原理。

砰!

第一个符号后缀!。这表明该方法应该是 destructive ,这意味着它修改了它被调用的对象。比较这两个脚本的输出:

a = [1, 2, 3]
a.map { |x| x * x }
a

a = [1, 2, 3]
a.map! { |x| x * x }
a

两个脚本之间存在一个字符差异,但它们的运行方式不同!第一个仍将遍历数组中的每个元素并在块内执行操作,但a中的对象仍然与您开始时的[1,2,3]相同。

但是,在第二个示例中,最后的a将改为[1, 4, 9],因为map!修改了对象!

查询

第二个符号后缀?,表示方法用于查询对象的某些内容,并表示该方法应该返回truefalse或某些extreme circumstancesnil

现在,请注意,方法不必返回truefalse ...只是如果它这样做会非常好!

证明:

def a?
  true
end

def b?
  "moo"
end

致电a?将返回true,并且致电b?将返回“moo”。那就是那个查询方法。 返回truefalse的方法,但有时会返回其他内容,因为某些开发人员不喜欢其他开发人员。

塞特斯!

现在我们了解你的(转述)问题: =在方法结束时的含义是什么?

这通常表示方法将设置一个特定值,如我在完成输入答案文章之前已经概述的Erik

但是,它可能不会设置一个,就像查询方法可能不会返回truefalse一样。这只是惯例。

你也可以像这样调用这个setter方法:

foo.something_else="value"

或(我最喜欢的):

foo.something_else = "value"

理论上,您实际上可以忽略传入的值,就像您可以完全忽略传递给任何方法的任何参数一样:

def foo?(*args)
  "moo"
end

>> foo?(:please, :oh, :please, :why, :"won't", :you, :use, :these, :arguments, :i, :got, :just, :for, :you, :question_mark?)
=> "moo"

Ruby支持setter方法的所有三种语法,尽管看到你使用的那种语法非常罕见!

好吧,我希望这个答案大致具有教育意义,并且您现在对Ruby有更多了解。享受!

答案 2 :(得分:3)

您无法为分配方法定义返回值。返回值始终与传入的值相同,因此赋值链(x = y = z = 3)将始终有效。

通常,在调用方法时会省略括号,因此它的行为类似于属性:

my_value = f.do_something= "drive"

答案 3 :(得分:0)

def do_something_else=action 
  action.inspect
end

这定义了一个setter方法,所以do_something_else就像我们正在初始化一个属性一样。所以初始化的值直接传递,