Как проверить, является ли объект Ruby логическим - PullRequest
114 голосов
/ 12 июня 2010

Кажется, я не могу легко проверить, является ли объект логическим. Есть ли что-то подобное в Ruby?

true.is_a?(Boolean)
false.is_a?(Boolean)

Сейчас я делаю это и хотел бы сократить это:

some_var = rand(1) == 1 ? true : false
(some_var.is_a?(TrueClass) || some_var.is_a?(FalseClass))

Ответы [ 9 ]

127 голосов
/ 13 июня 2010

Самый простой способ, которым я могу придумать:

# checking whether foo is a boolean
!!foo == foo
92 голосов
/ 09 сентября 2014

Я считаю это кратким и самодокументированным:

[true, false].include? foo

Если вы используете Rails или ActiveSupport, вы можете даже выполнить прямой запрос, используя in?

foo.in? [true, false]

Проверка на все возможные значения - это не то, что я бы рекомендовал для значений с плавающей запятой, но выполнимо, когда есть только два возможных значения!

84 голосов
/ 12 июня 2010

В Ruby нет класса Boolean, единственный способ проверить это - сделать то, что вы делаете (сравнивая объект с true и false или класс объекта с TrueClass и FalseClass).Не можете придумать, зачем вам эта функциональность, объясните?:)

Если вам действительно нужна эта функция, вы можете взломать ее:

module Boolean; end
class TrueClass; include Boolean; end
class FalseClass; include Boolean; end

true.is_a?(Boolean) #=> true
false.is_a?(Boolean) #=> true
22 голосов
/ 12 июня 2010

Как указано выше, нет логического класса, кроме TrueClass и FalseClass, однако вы можете использовать любой объект в качестве субъекта if / условии, если все верно, кроме экземпляров FalseClass и nil

Логические тесты возвращают экземплярFalseClass или TrueClass

(1 > 0).class #TrueClass

Следующий monkeypatch для Object скажет вам, является ли что-то экземпляром TrueClass или FalseClass

class Object
  def boolean?
    self.is_a?(TrueClass) || self.is_a?(FalseClass) 
  end
end

Запуск некоторых тестов с помощью irb дает следующие результаты

?> "String".boolean?
=> false
>> 1.boolean?
=> false
>> Time.now.boolean?
=> false
>> nil.boolean?
=> false
>> true.boolean?
=> true
>> false.boolean?
=> true
>> (1 ==1).boolean?
=> true
>> (1 ==2).boolean?
=> true
15 голосов
/ 12 июля 2013

Если ваш код может быть разумно написан как оператор case, это довольно прилично:

case mybool
when TrueClass, FalseClass
  puts "It's a bool!"
else
  puts "It's something else!"
end
5 голосов
/ 10 января 2013

Объект, который является логическим, будет иметь класс TrueClass или FalseClass, поэтому следующий однострочник должен выполнить трюк

mybool = true
mybool.class == TrueClass || mybool.class == FalseClass
=> true

Следующее также даст вам истинный / ложный результат проверки логического типа

mybool = true    
[TrueClass, FalseClass].include?(mybool.class)
=> true
4 голосов
/ 13 августа 2013

Так что попробуйте это (x == true) ^ (x == false) обратите внимание, вам нужна скобка, но это более красиво и компактно.

Он даже проходит предложенный как "cuak", но не "cuak" ... class X; def !; self end end ; x = X.new; (x == true) ^ (x == false)

Примечание : обратите внимание, что это настолько элементарно, что вы можете использовать его и на других языках, что не дает «вещь логическая».

Примечание 2 : Также вы можете использовать это, чтобы сказать, что вещь является одной из ??: "red", "green", "blue", если вы add more XORS ... или сказать, что эта вещь однаиз ??: 4, 5, 8, 35.

0 голосов
/ 19 декабря 2018

Этот гем добавляет в Ruby логический класс с полезными методами.

https://github.com/RISCfuture/boolean

Использование:

require 'boolean'

Тогда ваш

true.is_a?(Boolean)
false.is_a?(Boolean)

будет работать именно так, как вы ожидаете.

0 голосов
/ 24 мая 2017

Нет.Не так, как у вас есть свой код.Нет никакого класса с именем Boolean.Теперь со всеми имеющимися у вас ответами вы сможете создать и использовать его.Вы знаете, как создавать классы, не так ли?Я пришел сюда только потому, что мне самому была интересна эта идея.Многие могут сказать: «Почему? Вы просто должны знать, как Ruby использует Boolean».Вот почему вы получили ответы, которые вы сделали.Так что спасибо за вопрос.Пища для размышлений.Почему в Ruby нет логического класса?

NameError: uninitialized constant Boolean

Имейте в виду, что у объектов нет типов.Они классы.У объектов есть данные.Вот почему, когда вы говорите типы данных, это немного неправильно.

Также попробуйте rand 2, потому что rand 1, кажется, всегда дает 0. rand 2 даст 1 или 0 щелчок, выполненный несколько раз здесь.https://repl.it/IOPx/7

Хотя я и сам не знал бы, как создать булевы классы.Я экспериментировал с этим, но ...

class Boolean < TrueClass
  self
end

true.is_a?(Boolean) # => false
false.is_a?(Boolean) # => false

По крайней мере, у нас сейчас есть этот класс, но кто знает, как получить правильные значения?

...