繁体   English   中英

以`=`结尾的方法可以接受块吗?

[英]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会导致其他编译错误。

赋值方法应始终具有单个参数,其值可以分配给实例变量,或者其值可用于派生实例变量的新值。

如果您希望可以使用Proclambda作为参数,因为它们是对象。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM