Подкласс float, который можно оценить как ложный (нечеткая логика) в Ruby - PullRequest
1 голос
/ 04 ноября 2011

Мне нужен класс, который может представлять вероятности.Он может быть представлен как число с плавающей точкой от 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'

Из этого сообщения кажется, что это возможно: каждый объект имеет логическоеvalue ... Большинство объектов в Ruby будет иметь логическое значение true.Только два объекта имеют логическое значение false. Просто мне нужно как-то установить это логическое значение.Так возможно ли это?

Ответы [ 3 ]

5 голосов
/ 04 ноября 2011

Оператора «приведение к логическому значению» не существует, поскольку, как отмечает Дэвид, ложность жестко связана с 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

Все двойные удары могут быть немного уродливыми, но, с другой стороны, это может заставить людей заметить, что происходит что-то немного нестандартное.

5 голосов
/ 04 ноября 2011

Я хотел сделать что-то подобное, но, к сожалению, это невозможно в Ruby.

Единственные два объекта, которые имеют логическое значение false, это false и nil. Несколько недель назад у меня была дискуссия в интернет-чате (IRC) с Brixen , одним из главных разработчиков Rubinius, и он объяснил это довольно хорошо. Насколько я понимаю, когда Ruby решает, является ли объект истинным или нет, он НЕ вызывает какие-либо методы (то есть отправляет какие-либо сообщения) объекту, он просто смотрит на указатель на объект, чтобы увидеть, является ли указатель сам по себе. равно ложь или ноль. Поскольку он не вызывает никаких методов для объекта, вы не можете изменить поведение.

Лучшее, что вы можете сделать, это что-то вроде этого:

p = A.probability() 
puts p # => 0.3
if p.to_bool
  puts 'success'
else
  puts 'failure'
end
1 голос
/ 29 марта 2012

Прежде всего, вам не нужен подкласс Float.Те, кто заинтересован в создании подклассов Числовые типы, могут увидеть Кацуда ответ .

Простой способ достичь того, чего вы хотите достичь, - просто использовать метод:*

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 есть методы.

...