当方法名称不以=
结尾时,这似乎有效。
class C
def x= value = nil, &block
end
end
c = C.new
c.x = 1 # => fine
c.x=(2) # => fine
c.method(:x=).call { 3 } # => fine
c.x= { 4 } # => syntax error
c.x= do
5
end # => syntax error
有没有人知道为什么会这样,或者两种语法是否有相似的语法?
样本用法:
logger.level=(:debug) do
# log at debug level inside this block
end
当然有很多替代方案,例如:
logger.with_level(:debug) do
# log at debug level inside this block
end
我只是感兴趣,如果我在语法方面缺少某些内容,或者是否有人对此行为有任何解释。
答案 0 :(得分:3)
以=
结尾的方法称为Assignment methods,因此适用所有分配规则。
任何赋值语句都可以描述为
LHS = RHS
其中LHS
是左手边,RHS
是右手边。
RHS
被评估为LHS
的新值,如果使用尝试
要使用RHS
将块指定为{...}
,它将被解释为Hash文字的定义,并导致编译错误为无效散列。同样,do...end
块将导致其他编译错误。
赋值方法应始终具有单个参数,其值可以分配给实例变量,或者其值可用于为实例变量派生新值。
如果您希望可以使用Proc
或lambda
作为参数,因为它们是对象。
class C
def x= value
@x = (value.class == Proc ? value.call : value)
p @x
end
end
c = C.new
# fine
c.x = -> {10}
c.x = lambda {20}
c.x = Proc.new {30}
答案 1 :(得分:3)
他们可以,但以常规方式调用它们会导致块被评估为哈希,从而为您提供SyntaxError
。您仍然可以使用Object#public_send
/ Object#send
:
def foo=
puts 'bar'
yield
puts 'baz'
end
public_send(:foo=) { puts 'quiz' } # bar quiz baz
foo= { puts 'fail' } # SyntaxError