Как сделать так, чтобы в случае с оператором ruby ​​использовалось равенство (==), а не три (===) - PullRequest
0 голосов
/ 31 января 2019

В регистре Ruby по умолчанию используется ===.Есть ли способ заставить его использовать «равно» (то есть ==) вместо этого?

Мотивация для этого состоит в том, что у меня есть 5 if операторов, которые очень приятно заменить на переключатель,но я был немного удивлен, узнав, что

datatype = "string".class
if datatype == String
puts "This will print"
end

не совпадает с

case datatype
when String
puts "This will NOT print"
end

Ответы [ 4 ]

0 голосов
/ 31 января 2019

Вы также можете использовать явную форму оператора case

datatype = test_object.class

case
when datatype == String
  puts "It's a string"
when datatype < Numeric
  puts "It's a number"
end

Обратите внимание, что выражение тип данных будет истинным для всех числовых типов.

0 голосов
/ 31 января 2019

Это был бы более лаконичный и понятный подход (IMSO) к тому, что предложил @sawa.Используйте λ вместо класса оболочки.

META = ->(type, receiver) { receiver == type }

case "string".class
when META.curry[Integer] then puts 'integer'  
when META.curry[String] then puts 'string'  
end  

#⇒ "string"

В этом решении под капотом используются Proc#curry и Proc#===.

0 голосов
/ 31 января 2019

Аналогично ответу Алексея Матюшкина, но без карри:

is_class = ->(klass) { ->(item) { item == klass } }

10.times do
  case ['abc', 123].sample.class
  when is_class[String]
    puts "it's the abc"
  when is_class[Integer]
    puts "easy as 123"
  end
end

Что здесь происходит?

  • Первая строка определяет процесс, который возвращает другой процесс
  • proc[x] совпадает с proc.call(x)
  • proc.===(x) совпадает с proc.call(x)
  • is_class[Integer] возвращает прок, который делает { |val| val == Integer }
  • .. который вызывается в каждом случае с параметром case в качестве аргумента из-за === ==> call.

Большим недостатком является то, что он создает много процедур и выглядит странно.

Конечно, очевидным решением вашего вопроса было бы не делать datatype = "string".class:

datatype = "string"
case datatype
when String
puts "This will print"
end
0 голосов
/ 31 января 2019

Вы не можете позволить case не использовать ===, но вы можете переопределить === для использования ==.

class Class
  alias === ==
end

case datatype
when String
  puts "This will print"
end
# >> This will print

В качестве альтернативы, вы можете создать определенный класс дляделает это.

class MetaClass
  def initialize klass
    @klass = klass
  end

  def ===instance
    instance == @klass
  end
end

def meta klass
  MetaClass.new(klass)
end

case datatype
when meta(String)
  puts "This will print"
end
# >> This will print
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...