【问题标题】:Creating a setter method that takes extra arguments in Ruby在 Ruby 中创建一个接受额外参数的 setter 方法
【发布时间】:2011-01-23 18:14:27
【问题描述】:

我正在尝试编写一个方法,该方法充当 setter,并在分配的值之外接受一些额外的参数。愚蠢的例子:

class WordGenerator
  def []=(letter, position, allowed)
    puts "#{letter}#{allowed ? ' now' : ' no longer'} allowed at #{position}"
  end

  def allow=(letter, position, allowed)
    # ...
  end
end

把它写成索引器是可行的,我可以这样称呼它:

gen = WordGenerator.new

gen['a', 1] = true
# or explicitly:
gen.[]=('a', 1, true)

但是当我尝试以下任何一种方法时,口译员会抱怨:

gen.allow('a', 1) = false # syntax error
gen.allow=('a', 1, false) # syntax error

为什么这不起作用,我错过了显而易见的事情吗?

【问题讨论】:

标签: ruby methods setter indexer


【解决方案1】:

它不起作用,因为解析器不允许它。在 identifier = expressionexpression.identifier = expression(其中标识符为 \w+)、expression[arguments] = expressionexpression.[]= arguments 形式的表达式中允许使用等号,并作为字符串或符号或字符文字 (?=) 的一部分。就是这样。

gen.send(:allow=, 'a', 1, false) 可以工作,但此时您也可以只为该方法指定一个不包含 = 的名称。

【讨论】:

  • 谢谢。有趣的是它允许像 'def seed=(value) end; 这样的东西。 gen.seed=(1)'。我本来希望 'seed=' 是标识符,但是(如果我正确理解您的规则)它就像:[gen/expr].[seed/identifier]=[(1)/expr]。这可以解释为什么它会因多个参数而失败——(a) 是一个表达式,但是 (a, b) 不是!假设这成立,'gen.[]=('a', 1, true)' 是如何工作的?
  • .[]= 是我在上面的列表中忘记的另一个特殊情况(与expression[comma_seperated_expressions] = expression 一起,当然也可以)。
【解决方案2】:

我遇到了这个问题,并决定将我的参数作为数组或散列传递。

例如:

def allow=(arguments)
  puts arguments[:letter]
  puts arguments[:position]
  puts arguments[:allowed]
end

object.allow={:letter=>'A',:position=>3,:allowed=>true}

【讨论】:

    猜你喜欢
    • 2015-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-28
    • 1970-01-01
    • 2012-09-26
    • 1970-01-01
    相关资源
    最近更新 更多