在 Ruby 中可以评估为 false(模糊逻辑)的 float 子类

发布于 2024-12-13 21:33:32 字数 456 浏览 1 评论 0原文

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

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

从此 post 似乎表明这是可能的:每个对象都有一个布尔值...Ruby 中的大多数对象都有一个布尔值 true。只有两个对象的布尔值是 false。只是我需要以某种方式设置这个布尔值。那么这可能吗?

I need a class that can represent probabilities. It can be represented like a float between 0 and 1, and anything below 0.5 should evaluate to false. (or it can be between 1 and -1, anything negative is false)

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

From this post it seems to suggest it is possible: every object has a boolean value... Most objects in Ruby will have a boolean value of true. Only two objects have a boolean value of false. Just that I need to set this boolean value somehow. So is this possible?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

会发光的星星闪亮亮i 2024-12-20 21:33:32

我想做类似的事情,但不幸的是这在 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

I wanted to do something similar, but unfortunately this is not possible in Ruby.

The only two objects that have a boolean value of false are false itself and nil. A few weeks ago I had a an internet chat (IRC) discussion with Brixen, one of the main developers of rubinius, and he explained it pretty well. My understanding is that when Ruby decides whether an object is true or not, it does NOT call any methods on (i.e. send any messages to) the object, it simply looks at the pointer it has to the object to see whether the pointer itself is equal to false or nil. Since it doesn't call any methods on the object, there is no way for you to change the behavior.

The best you can do is something like this:

p = A.probability() 
puts p # => 0.3
if p.to_bool
  puts 'success'
else
  puts 'failure'
end
哆兒滾 2024-12-20 21:33:32

没有“强制转换为布尔值”运算符,因为正如 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

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

There is no "cast to boolean" operator because, as David notes, falsiness is hard wired for false and nil and anything that isn't "falsy" is true. However, there is a logical negation operator so you can do it if you don't mind an explicit cast to boolean:

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

And then:

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

All the double bangs might be a bit ugly but, on the upside, it might make people notice that something a little non-standard is going on.

我恋#小黄人 2024-12-20 21:33:32

首先,您不需要 Float 子类。对数字类型子类化感兴趣的人可以参阅 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 有方法。

First of all, you do not need a Float subclass. Those interested in subclassing Numeric types can see Katzuda's answer.

The simple way to achieve what you want to achieve is to simply use a method:

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

Remember, for these kind of circumstances, Ruby has methods.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文