Вызывает ли оператор if в Ruby конкретный объектный метод? - PullRequest
0 голосов
/ 02 февраля 2019

Может быть, я не совсем понимаю что-то фундаментальное, но мне было интересно, вызывается ли какой-то конкретный метод объекта при оценке его для оператора if?

Итак, ниже ...

my_object = MyObject.new

if !my_object
  puts 'Hello, world!'
end

class MyObject
  def ___
    return false
  end
end

... есть ли какой-нибудь метод ___, который я мог бы определить в объекте, который вызывался бы с помощью if, чтобы я мог определить результат условного выражения?(в приведенном выше примере выводом будет «Hello, world!»)

Или есть какой-то другой способ, которым я, из определения MyObject, могу контролировать, как он будет оцениваться в if Скажите?

Спасибо.

Ответы [ 2 ]

0 голосов
/ 03 февраля 2019

существует ли какой-либо метод ___, который я мог бы определить в объекте, который вызывался бы с помощью if, чтобы я мог определить результат условного выражения?

Нет,к сожалению нет.Это один из случаев, когда Ruby, к сожалению, не объектно-ориентирован.

В Ruby есть только два ложных объекта: false (очевидно) и nil.Все остальное является правдой, включая объекты, которые считаются ложными в некоторых других языках, например, целое число 0, число с плавающей запятой 0.0, пустая строка '', пустой массив [] и пустой хеш {}.

Один из фундаментальных столпов объектной ориентации состоит в том, что объекты могут имитировать друг друга.Фактически, некоторые люди утверждают, что это определяющая особенность объектной ориентации.Тем не менее, в Ruby нет способа имитировать false или nil.

(в приведенном выше примере выводом будет «Hello, world!»)

В этом конкретном случае вы могли бы добиться этого, переопределив !, но это было бы обманом, поскольку это не влияет на истинное значение самого объекта:

class MyObject
  def !
    true
  end
end
0 голосов
/ 02 февраля 2019

Значение if должно преобразовываться в true, если переменная отличается от nil или false (и будет ошибка, если переменная не определена).Я не уверен, что есть способ переопределить объект, который определен так, чтобы возвращать ноль или ложь (это не смущает большинство программистов на Ruby), но мне было бы интересно услышать от других.

Чтовы можете добавить метод, возвращающий значение nil или false, и использовать его вместо этого:

class MyObject
  def foo?
    false
  end
end

obj = MyObject.new

if obj.foo?
  puts "true"
else
  puts "false"
end

Обновление: метод new можно переопределить, чтобы получить логическое значение, а неobject.

class MyObject
  attr_reader :var

  def initialize(*args)
    args.each do |a|
      puts a
    end
  end

  def self.new(*args, &block)
    super
    false
  end
end

my_object = MyObject.new(:a, :b)

if !my_object
  puts 'Hello, world!'
end


my_object = MyObject.new

if !my_object
  puts 'Hello, world!'
end

С этим может быть любое количество побочных эффектов, так как вы в основном конвертировали экземпляр объекта в логическое значение.Хотя это может быть интересным исследованием, но я, вероятно, буду придерживаться изменения своего назначения или выполнения проверки defined?, is_a?, nil? или иным образом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...