У меня есть хэш, скажем:
ahash = {test1: "test1", test2: "test2"}
Почему это, что Hash === ahash
возвращает true, но ahash === Hash
нет? Является ли это некоторым поведением рубина по умолчанию с === и именем класса?
У меня есть хэш, скажем:
ahash = {test1: "test1", test2: "test2"}
Почему это, что Hash === ahash
возвращает true, но ahash === Hash
нет? Является ли это некоторым поведением рубина по умолчанию с === и именем класса?
Как работает метод ===
. Он направлен и применяется к любому классу:
"foo" === String
# => false
String === "foo"
# => true
Это потому, что это оценивается как:
"foo".send(:===, String)
String.send(:===, "foo")
Это два разных метода: один для класса, один для экземпляра.
Если вы интересуетесь только информацией о классе:
"foo".is_a?(String)
# => true
{ }.is_a?(Hash)
# => true
Этот метод значительно упрощает ваше намерение.
Модуль # === (также называемый "оператор равенства случая" ) возвращает true, если объект в правой части выражения является экземпляром левая сторона или один из ее потомков. Когда вы спросите:
Hash === {test1: "test1", test2: "test2"}
то, что вы действительно спрашиваете, таково: "Является ли этот хэш буквальным экземпляром или потомком класса Hash?" С другой стороны, обратное неверно, так как класс Hash не является экземпляром или потомком вашего хеш-литерала.
С другой стороны, следующее работает в любом случае:
Hash.new === {}
{} === Hash.new
поскольку оба выражения эквивалентны случаю. Здесь же результат, используя ваши данные:
Hash[:test1, "test1", :test2, "test2"] === {:test1=>"test1", :test2=>"test2"}
#=> true
{:test1=>"test1", :test2=>"test2"} === Hash[:test1, "test1", :test2, "test2"]
#=> true
Однако, триquals - это не просто stand-in для Object # is_a?. Это действительно предназначалось для потребления в случаях/когда заявления, а Джайлс Бокетт говорит:
Существует метод === для управления тем, как блок/блок будет оценивать объект. Он никогда не должен использоваться людьми. Это код, написанный для потребления другим кодом, в частности, в случае и когда.