簡體   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