Pull to refresh

Comments 26

Статья неплохая, но совсем не раскрыта особенности объектов типа Symbol
Например:
a = :test
b = :test
a.equal?(b) => true
верно, спасибо. но вы как раз и раскрыли все, что нужно сказать о равенстве символов в 3 строках кода. тем более я не знаю, есть ли вообще необходимость их сравнивать или проверять на равенство.
Об Symbol можете почитать здесь.
Если коротко, то экземпляры этого класса являются синглетонами, то есть указывают на один и тот же объект. Это легко проверить:
a = :foo
b = :foo
a.object_id #=> 307548
b.object_id #=> 307548
Я бы еще добавил, что именно поэтому не рекомендуется злоупотреблять символами там где это не надо. Ну по есть например преобразовывать строки в символы в адских циклах. Потому что символы не удаляются из памяти. Кстати, это по прежнему так?
В 1,9,2 по-прежнему так.
Есть просто правило: все статические строки, если они используются в коде не один раз, загонять в символы. Получается небольшой дополнительный расход памяти взамен на небольшой прирост производительности, так как символы сравниваются намного быстрее.
> puts /p*cock/ === 'peacock' #true
Какие в Ruby интересные регулярные выражения. Во всех других языках шаблону p*cock будет соответствовать pppcock.
Вообще-то, поведение вполне одинаковое

'peacock'.scan(/p*cock/) #=> ["cock"]
$c = preg_match('/p*cock/', 'peacock', $m); #=> $m = ["cock"], $c = 1
вы правы, правильное выражение /p.*cock/, теперь исправлено. спасибо.
Если для начинающих, то надо было бы начинать с различных методов присваивания… меня в ступор вводили записи ||= и |= и т.п. (-:
Всё просто: a = a||10 тоже самое что a ||= 10. То есть если значение a не определено, что переменной присваивается значение 10. С другими операторами присваивания тоже самое.
Это сейчас, когда это знаешь, это просто, а вот в начале совсем не понятно было, когда первый раз сталкиваешься (-:
Если прочитать документацию, то всё просто, если не читать — сложно :) Тут нет какой-то особой концепции, трудной для понимания. Всего лишь синтаксический сахар.
Он определен у класса Object и не может быть переписан в дочерних классах.
Это не так, любой метод может быть переопредлён. Это можно проверить:
class Foo
  def equal?(other)
    "fuu"
  end
end
a = Foo.new
a.equal? "test" #=> "fuu"
<source>
Главное понимать к чему такое переопределение может привести.
Более того, вы можете переопределить метод equal? и у класса Object. Правда это поломает руби.
<source lang=ruby>class Object
  def equal? other
    "broken ruby"
  end
end
1.equal? 1 #=>  "broken ruby"
Из документации:
о классе Object

Unlike ==, the equal? method should never be overridden by subclasses: it is used to determine object identity (that is, a.equal?(b) iff a is the same object as b).
>should never be overridden by subclasses

значит что это не стоит делать, но возможность такое сделать имеется.
Мои примеры кажутся вам не убедительными?

«should never be overridden by subclasses» переводится как «не должен быть переопределён в подклассе». Не может не тоже самое что не должен. В руби можно переопределить любые методы, но переопределение некоторых может поломать поведение многих объектов. Метод equal? как раз такой.

Утверждая, что что-то не может быть переопределено, вы говорите, что в объектной модели руби есть какие-то магические исключения, которых там на самом деле нет.
да, в конце концов вы правы. такая возможность существует.
Исправьте, пожалуйста, ошибку в статье.
Полагаю, незаслуженно обойдён вниманием ценный оператор "===", который, с одной стороны, определён как проверка принадлежности классу в классе Object:

String === 'a'
Fixnum === 42
FalseClass === false
Array === [42]
Hash === {всё_такое: 42}
# это всё вернёт true


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

case a
when /foo/ then ...
when 'bar' then ...
when String then ...
when nil then ...
else ....
end
=== — это не совсем проверка принадлежности классу.
Функция проверяет принадлежность не только классу, но и принадлежит ли объект потомку этого класса. То есть
Numeric === 42
Integer === 42
Fixnum === 42

это все вернет true. То есть то же самое, что делает kinf_of?()
Для проверки принадлежности классу используется instance_of?()
Да, вообще не раскрыт оператор ===. Вот банальным гуглением нашел пример из более подробной статьи.
a = Object.new
a === a                             # true
a === Object.new                    # false
"foo"           === "foo"           # true
"foo".object_id == "foo".object_id  # false
1 === 1.0                           # true
1.class == 1.0.class                # false
Fixnum  === 1                       # true
(1..10) === 5                       # true
/o/ === 'foo'                       # true

Да и ничего не сказано про =~.
Использовали бы лучше в статье <source lang="ruby">…<source>
Sign up to leave a comment.

Articles