让我们说我有一个Ruby类:

class MyClass
  def self.property
    return "someVal"
  end

  def self.property=(newVal)
    # do something to set "property"
    success = true

    return success # success is a boolean
  end
end

如果我尝试做MyClass.property=x,整个语句的返回值始终是X。这是一个很大的一个约定基于C /启发语言返回一个布尔值“成功”的价值 - 是有可能使用二传手做这在Ruby中的“等于语法”

此外 - 如果这是不可能的,为什么不呢?是否有任何可以想到的缺点允许“等于设定器”操作返回一个值?

有帮助吗?

解决方案

一个缺点是,你将打破链赋值语义:

$ irb 
irb(main):001:0> x = y = 3
=> 3
irb(main):002:0> p x
3
=> nil
irb(main):003:0> p y
3
=> nil
irb(main):004:0> 

考虑:

x = MyClass.property = 3

然后x将采取true如果它工作,因为你的预期(右关联)。这可能是使用接口的人一个惊喜,并用典型的语义。

您也让我想起了平行作业,如:

x, y = 1, 2

显然从该表达式返回值是执行特定 ...我想我将不被链接平行分配:)

尼斯问题!

其他提示

就像马丁说,这将打破分配链。

红宝石分配方法定义为工作的方式扩展到MyClass.property = 3(lambda { |v| MyClass.send('property=', v); v })[3]相当于(不是真的,但是这显示了如何链接的作品)。分配的返回值是始终分配的值。

如果你想看到你的MyClass#property=方法的结果,然后使用#send

irb> o = Object.new
=> #<Object:0x15270>
irb> def o.x=(y)
irb>   @x = y+1
irb>   puts "y = #{y}, @x = #@x"
irb>   true
irb> end
=> nil
irb> def o.x
irb>   puts "@x = #@x"
irb>   @x
irb> end
=> nil
irb> o.x = 4
y = 4, @x = 5
=> 4
irb> o.x
@x = 5
=> 5
irb> o.send('x=', 3)
y = 3, @x = 4
=> true

不过,红宝石的方式来做到这一点是例外 - 如果期间出现了错误 分配时,抛出一个异常。然后,如果出现所有调用者必须处理它 错,与一个返回值,可以很容易地忽略:

# continued from above...
irb> def o.x=(y)
irb>   unless y.respond_to? :> and (y > 0 rescue false)
irb>     raise ArgumentError, 'new value must be > 0', caller
irb>   end
irb>   @x = y + 1
irb>   puts "y = #{y}, @x = #@x"
irb> end
=> nil
irb> o.x = 4
y = 4, @x = 5
=> 4
irb> o.x = 0
ArgumentError: new value must be > 0
    from (irb):12
    from :0
irb> o.x = "3"
ArgumentError: new value must be > 0
    from (irb):13
    from :0
irb> o.x
@x = 5
=> 5

我不是一个Ruby专家,但我会说没有为这种情况下,我害怕。属性setter仅仅是有设置私有字段的值,不具有任何副作用,如返回结果代码。

如果你想那么该功能忘了setter和谱写新的方法叫做TrySetProperty或一些东西,试图设置属性,并返回一个布尔值。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top