我需要一个可以代表概率的类。它可以表示为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'
从这个post看来它似乎有可能:每个对象都有一个布尔值...... Ruby中的大多数对象都有一个布尔值为true。只有两个对象的布尔值为false。只是我需要以某种方式设置此布尔值。这可能吗?
答案 0 :(得分:5)
我想做类似的事情,但不幸的是,这在Ruby中是不可能的。
布尔值为false的唯一两个对象是false
本身和nil
。几个星期前,我与rubinius的主要开发人员之一Brixen进行了一次互联网聊天(IRC)讨论,他解释得非常好。我的理解是,当Ruby决定一个对象是否为真时,它不会调用任何方法(即发送任何消息)对象,它只是查看它对象的指针,看看指针本身是否是等于假或零。由于它不会调用对象上的任何方法,因此无法更改行为。
你能做的最好的事情就是这样:
p = A.probability()
puts p # => 0.3
if p.to_bool
puts 'success'
else
puts 'failure'
end
答案 1 :(得分:5)
没有“强制转换为布尔值”运算符,因为正如David所说,false
和nil
的虚假性很难,任何不是“伪”的都是真的。但是,有一个逻辑否定运算符,所以你可以这样做,如果你不介意显式转换为布尔值:
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
所有的双重刘海可能有点难看,但从好的方面来说,它可能会让人们注意到一些不合标准的东西。
答案 2 :(得分:1)
首先,您不需要Float子类。那些对子类化数字类型感兴趣的人可以看到Katzuda的answer。
实现您想要实现的目标的简单方法是简单地使用方法:
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有方法。