[英]Can methods that end with `=` accept blocks?
当方法名称不以=
结尾时,这似乎有效。
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
我只是感兴趣,如果我错过了语法方面的东西,或者如果有人对此行为有任何解释。
以=
结尾的方法称为赋值方法 ,因此所有赋值规则都适用。
任何赋值语句都可以描述为
LHS = RHS
LHS
是左手侧, RHS
是右手侧。
RHS
被评估为LHS
的新值,并且如果使用尝试使用{...}
将块指定为RHS
,则它将被解释为Hash文字的定义,并导致编译错误为无效散列。 同样, do...end
block会导致其他编译错误。
赋值方法应始终具有单个参数,其值可以分配给实例变量,或者其值可用于派生实例变量的新值。
如果您希望可以使用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}
他们可以,但以常规方式调用它们会导致块被评估为哈希,从而为您提供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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.