Pull to refresh

Comments 27

Гуд. Еще был перевести магию class << self ;) клянусь, констракт для меня странноватый.
Там на самом деле все просто, но если есть необходимость, то найду хорошую статью на эту тему.
Было бы здорово, если это не статья типа «делай так, и всё будет круто».
Де факто, это для меня единственная магия в Ruby. Остальное естественно и понятно.
Изучил вопрос. Никакой магии оказывается, действительно вот такой вот синтаксис просто, а означает он как раз доступ к синглтон-классу объекта.

class Car
  def self.number
    # ...
  end
end

# тоже самое, что и...

class Car; end
class << Car # мы внутри синглтон-класса класса Car
  def number
    # ...
  end
end

# тоже самое, что и...

class Car
  # self == Car, поэтому мы снова внутри синглтон-класса Car
  class << self
    def number
      # ...
    end
  end
end

Или…

class Car; end

bmw = Car.new

class << bmw # мы внутри синглтон-класса объекта bmw
  def number
    'abc'
  end
end

# тоже самое, что и...

def bmw.number
  'abc'
end

bmw.number #=> 'abc'

Т.е. никакого дополнительного скрытого смысла, просто такой синтаксис. Почему Matz его придумал таким — надо у него спросить :)
Подозреваю, что "<<" следует понимать как «на один уровень назад». Синглтон он ведь незаметно встраивается в цепочку наследования, то есть фактически является родителем текущего класса, и вот такой «стрелкой» мы какбы показываем, что идет обращение назад — к предку. Я всегда так себе это представлял.
Конечно. Статьи типа «делай так» и читать и переводить неинтересно :)
Мне кажется, что Акжан шутит, ибо будучи ruby-программистом и активным автором в хабы ruby/rails он 100% знает о class << self.
Не шучу. Я понимаю смысл, но не понимаю синтаксиса (почему именно так?). Мог бы посмотреть, но с первого взгляда не нашёл, а дальше рыть не стал. Работает, и ладно. Лишь иногда возникает ощущение недопонятости.
Спасибо, хороший материал.
Прочитайте главу про метапрограммирование в Thomas D., Fowler C., Hunt A. — Programming Ruby 1.9, updated for Ruby 1.9.2 (The Pragmatic Programmers) — 2010
Авторы достаточно подробно и понятно объясняют.
Спасибо, гляну в этом месяце.
Чего не понятно? Класс — это объект (если не вникать сильно во внутреннее устройство), для объекта мы вызываем метод #extend, чтобы подмешать модуль. А include используется для расширения экземпляров класса. Все понятно и без статьи.
Ну как бы из статьи понятно, что все не так уж просто и понятно. Очень многие вещи часто понятны в общих чертах, тем не менее разложенные по полочкам подробности реализации вносят дополнительную ясность в мысли, а кроме того закладывают хороший фундамент для дальнейшего расширения и углубления знаний.
Здесь всё-таки подробнее/точнее. Затронута тема сингтонов, не хватает лишь деталей, ибо не все понятно тем, кто уже пишет на Ruby.
Ну с синглтонами все понятно, да и не вижу смысла разбираться сильно с ними… Не видел еще, чтобы кто-то их непосредственно использовал, то есть осознано. Хотя если просто интересно как оно работает, то да, тогда статья имеет смысл, а не практике — сомневаюсь.
О! Кто-то люто минусует. Велкам ту май карма!
Более понятно и более развернуто это дело описано в книге Metaprogramming Ruby. Очень достойная книга, но не для новичков.
+1 отличная книга и доходчиво написана. Если не ошибаюсь, она на 1.8 ориентирована, но на 99% все еще актуальна.
Странно что там постоянно аналогии с Java приводятся :-) Но книжка хорошая.
Из Java многие на Ruby/jRuby переходят, вот и автор, наверное, один из таких перебезчиков.
Автор хорошо описал механизм eigenclass'а, возможно для понимания конструкции вида class << self не хватает некоторых знаний о других механизмах языка, вроде Scope Gates.

Я крайне советую вам прочитать Metaprogramming Ruby, очень многое станет на свои места media.pragprog.com/titles/ppmetr/spells.pdf Там автор более продробно разбирает механизм (в том числе и с наследованием), приводит еще несколько извращений с eigenclassами.

Если нет времени читать всю книгу (а она того стоит!), то вот более подробная статья, www.madebydna.com/all/code/2011/06/24/eigenclasses-demystified.html Статья актуальна для 1.9, в 1.8 не было BasicObject, но кому сейчас нужен 1.8 :)

Когда начинаешь копать глубже типичного использования include и extend, то обнаруживаешь нечто странное и пугающее. Однако стоит понять реализацию лежащую в основе и все сразу обретает смысл.


Когда начинаешь разбираться, что происходит внутри объекта main, это ощущение возвращается:

banisterfiend.wordpress.com/2010/11/23/what-is-the-ruby-top-level/

А подскажите вот еще какой вопрос. Я написал модуль, в котором переопределил метод .downcase класса String. Но не при include, ни при extend он не вызывается — вызывается стандартный метод объекта String. Исходя из описания, это должно работать при extend, но увы — что-то я не так понял. То есть интересует следующее

module M1
def downcase
return 'Hello!'
end
end

class String
include M1
end

'Привет'.downcase
=> «Привет»

У меня независимо от использования include и extend — всегда возвращается 'Привет'. Как правильно переопределять существующие методы?
Если строка содержит только латинские символы, то все должно работать.

Для символов кириллицы попробуйте использовать метод mb_chars (нужен джем 'activesupport'):

"Привет".mb_chars.downcase

Sign up to leave a comment.

Articles