对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"
第一个例子是自我解释。我试图理解的是第二个例子的行为。除了看起来是一个产生字符串文字,而另一个不是,实际发生了什么?为什么我会使用一个而不是另一个?
答案 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!
修改了对象!
第二个符号后缀是?
,表示方法用于查询对象的某些内容,并表示该方法应该返回true
,false
或某些extreme circumstances,nil
。
现在,请注意,方法不必返回true
或false
...只是如果它这样做会非常好!
证明:
def a?
true
end
def b?
"moo"
end
致电a?
将返回true
,并且致电b?
将返回“moo”。那就是那个查询方法。 应返回true
或false
的方法,但有时会返回其他内容,因为某些开发人员不喜欢其他开发人员。
现在我们了解你的(转述)问题: =
在方法结束时的含义是什么?
这通常表示方法将设置一个特定值,如我在完成输入答案文章之前已经概述的Erik。
但是,它可能不会设置一个,就像查询方法可能不会返回true
或false
一样。这只是惯例。
你也可以像这样调用这个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就像我们正在初始化一个属性一样。所以初始化的值直接传递,