1

我需要一个可以表示概率的类。它可以表示为 0 和 1 之间的浮点数,低于 0.5 的任何值都应评估为 false。(或者它可以在 1 和 -1 之间,任何负数都是假的)

p = A.probability() 
puts p # will output 0.3
if(p)
  puts 'success'
else
  puts 'failure'
end
# will outputs 'failure'

从这篇文章看来,这是可能的:每个对象都有一个布尔值...... Ruby 中的大多数对象都有一个布尔值 true。只有两个对象的布尔值为 false。只是我需要以某种方式设置这个布尔值。那么这可能吗?

4

3 回答 3

5

我想做类似的事情,但不幸的是,这在 Ruby 中是不可能的。

布尔值为 false 的唯一两个对象是false它自己和nil. 几周前,我与rubinius 的主要开发者之一Brixen进行了一次互联网聊天 (IRC) 讨论,他很好地解释了这一点。我的理解是,当 Ruby 决定一个对象是否为真时,它不会调用该对象的任何方法(即向该对象发送任何消息),它只是查看它拥有的指向该对象的指针以查看指针本身是否为等于 false 或 nil。由于它不调用对象上的任何方法,因此您无法更改行为。

你能做的最好的事情是这样的:

p = A.probability() 
puts p # => 0.3
if p.to_bool
  puts 'success'
else
  puts 'failure'
end
于 2011-11-04T06:32:42.293 回答
5

没有“转换为布尔值”运算符,因为正如大卫指出的那样,虚假是硬连线的falsenil并且任何不是“虚假”的东西都是真实的。但是,有一个逻辑否定运算符,因此如果您不介意显式转换为布尔值,您可以这样做:

class P
    attr_accessor :p
    def !@
        p < 0.5
    end
end

进而:

>> p = P.new
>> p.p = 0.75
=> puts 'Pancakes!' if(!!p)
Pancakes!
>> p.p = 0.25
>> puts 'Pancakes!' if(!!p)
# No pancakes for you

所有的双刘海可能有点难看,但从好的方面来说,它可能会让人们注意到一些不标准的事情正在发生。

于 2011-11-04T06:41:42.087 回答
1

首先,您不需要 Float 子类。那些对 Numeric 类型的子类化感兴趣的人可以查看Katzuda回答

实现您想要实现的简单方法是简单地使用一个方法:

class P
  def initialize p; @p = p
    raise "outta range" unless 0 <= @p and @p <= 1 end
  def success?; SUCC <= @p end
  def fail?; not success? end
end

p = P.new 0.3
p.success? # => false
p.fail? # => true

q = P.new 0.7
q.success? # => true
q.fail? # => false

请记住,对于这种情况,Ruby 有方法。

于 2012-03-29T13:08:48.350 回答