[英]Can methods that end with `=` accept blocks?
This seems to work when the method name doesn't end in =
. 当方法名称不以=
结尾时,这似乎有效。
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
Does anyone have any idea why this is, or whether there is a similar syntax to the two that don't work? 有没有人知道为什么会这样,或者是否有两种类似的语法不起作用?
sample usage: 样品用量:
logger.level=(:debug) do
# log at debug level inside this block
end
there are of course many alternatives, such as: 当然有很多替代品,例如:
logger.with_level(:debug) do
# log at debug level inside this block
end
i am just interested if i was missing something syntax-wise or if anyone had any explanation for this behavior. 我只是感兴趣,如果我错过了语法方面的东西,或者如果有人对此行为有任何解释。
Methods ending with =
are called Assignment methods , and as such all rules of assignment applies. 以=
结尾的方法称为赋值方法 ,因此所有赋值规则都适用。
Any assignment statement can be depicted as 任何赋值语句都可以描述为
LHS = RHS
where LHS
is Left Hand Side, RHS
is Right Hand Side. LHS
是左手侧, RHS
是右手侧。
The RHS
is evaluated to be a new value for LHS
, and if use attempt to specify block as RHS
using {...}
, it will get interpreted as definition of Hash literal and result in compilation error for being invalid hash. RHS
被评估为LHS
的新值,并且如果使用尝试使用{...}
将块指定为RHS
,则它将被解释为Hash文字的定义,并导致编译错误为无效散列。 Similarly, do...end
block will result in other compilation errors. 同样, do...end
block会导致其他编译错误。
Assignment methods should always have single parameter whose value can be assigned to an instance variable, or whose value can be used to derive new value for the instance variable. 赋值方法应始终具有单个参数,其值可以分配给实例变量,或者其值可用于派生实例变量的新值。
If you wish you can use Proc
or lambda
as parameter, as they are Objects. 如果您希望可以使用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}
They can, but calling them the regular way would cause the block to be evaluated as hash thus giving you SyntaxError
. 他们可以,但以常规方式调用它们会导致块被评估为哈希,从而为您提供SyntaxError
。 You can still call them using Object#public_send
/ Object#send
: 您仍然可以使用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.