一个float子类,可以在Ruby中求值为false(模糊逻辑)

时间:2011-11-04 06:20:05

标签: ruby boolean fuzzy-logic

我需要一个可以代表概率的类。它可以表示为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。只是我需要以某种方式设置此布尔值。这可能吗?

3 个答案:

答案 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所说,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

所有的双重刘海可能有点难看,但从好的方面来说,它可能会让人们注意到一些不合标准的东西。

答案 2 :(得分:1)

首先,您不需要Float子类。那些对子类化数字类型感兴趣的人可以看到Katzudaanswer

实现您想要实现的目标的简单方法是简单地使用方法:

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有方法。