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

lul*_*ala 1 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'
Run Code Online (Sandbox Code Playgroud)

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

Dav*_*son 5

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

布尔值为false的唯一两个对象false本身就是nil.几个星期前,我与布里克森进行了一次互联网聊天(IRC)讨论,布里克森是rubinius的主要开发者之一,他对此进行了很好的解释.我的理解是,当Ruby决定一个对象是否为真时,它不会调用任何方法(即发送任何消息)对象,它只是查看它对象的指针,看看指针本身是否是等于假或零.由于它不会调用对象上的任何方法,因此您无法更改行为.

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

p = A.probability() 
puts p # => 0.3
if p.to_bool
  puts 'success'
else
  puts 'failure'
end
Run Code Online (Sandbox Code Playgroud)

  • 如果你浏览源代码,你会发现`Qfalse`,`Qtrue`和`Qnil`的硬连线值; 在`ruby.h`中查找`enum ruby​​_special_consts`,你会在下面看到C枚举和一些`#define`s. (3认同)

mu *_*ort 5

没有"强制转换为布尔"操作符,因为正如David所说,虚假是强硬连接的false,nil并且任何不是"虚假"的东西都是真的.但是,有一个逻辑否定运算符,所以如果你不介意显式转换为布尔值,你可以这样做:

class P
    attr_accessor :p
    def !@
        p < 0.5
    end
end
Run Code Online (Sandbox Code Playgroud)

然后:

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

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