Как стать автором
Обновить

Комментарии 32

дерзайте! Главное не останавливаться.

Успехов Вам и новых капель :)
ех. а я неуспеваю… бысренько капает.
но всеравно спасибо — в избранное!
> при включении (include) модуля в класс, его методы добавляются в класс

если более точно, то методы не добавляются в класс, а создается хидден прокси-класс, который вклинивается в цепь наследования классов, и становится родителем для класса объекта. При этом, если класс «А» уже был отнаследован от какого-нибудь класса (например, «B»), то, повторю, родителем класса «А» становится прокси-класс, а уже родителем прокси-класса — класс «B»
НЛО прилетело и опубликовало эту надпись здесь
Он, наверное, имел в виду:

irb(main):001:0> class A; end
irb(main):002:0> class B < A; end
irb(main):003:0> B.ancestors
=> [B, A, Object, Kernel]
irb(main):004:0> module C; end
irb(main):005:0> class B; include C; end
irb(main):006:0> B.ancestors
=> [B, C, A, Object, Kernel]

> => [B, C, A, Object, Kernel]

ага, только это .ancestors выдает «C», и, с человеческой точки зрения, это, действительно, так; с машинной же точки зрения — там создается прокси-класс, который имеет ссылку на «C»
> Такое происходит, когда объявляешь метод для конкретного экземпляра.
Когда объявляешь методы для экземпляра, создает также virtual-класс для объекта, который и хранит методы конкретного инстанса. Таким образом цепь наследования класса следующая: virtual-класс объекта -> класс объекта -> прокси-класс на модуль (может быть несколько) -> super-класс -> и т.д. super-классы.

> А вот при включении модулей методы, кажется, никуда не копируются.

Так методы никуда и не копируются. Создается прокси-класс, который ссылается на модуль. И этот прокси класс становится super-классом для класса объекта.
Там сказано, опять же, с человеческой точки зрения (т.е. подмешанные методы будут доступны инстансу класса), однако, там ничего не сказано про техническую реализацию. А техническая реализация (с машинной точки зрения) такая, что, все-таки, создается хидден-прокси-класс, который ссылается на модуль, и который становится super-классом для классам объекта.

Это можно посмотреть на примере (модуль подмешивается, однако, затем метод модуля изменяется и объект использует уже новый метод; в то время, как, если рассматривать ваше предположение, то слоты модуля должны подмешиваться к каждому классу свои и становится независимыми от модуля, но это не так):

irb(main):001:0> module A
irb(main):002:1>   def a
irb(main):003:2>     puts "A.a"
irb(main):004:2>   end
irb(main):005:1> end
=> nil
irb(main):006:0> class B; end
=> nil
irb(main):007:0> class C < B
irb(main):008:1>   include A
irb(main):009:1> end
=> C
irb(main):010:0> d = C.new
=> #<C:0x81d22f4>
irb(main):011:0> d.a
A.a
=> nil
irb(main):012:0> module A
irb(main):013:1>   def a
irb(main):014:2>     puts "New A.a"
irb(main):015:2>   end
irb(main):016:1> end
=> nil
irb(main):017:0> d.a
New A.a
Спасибо за пример, конечно это более логично. Я сам не выдержал, поставил себе Ruby и уже поигрался в консоли )
Что-то мне кажется рановото для рельс, хотя и в консоли не интересно :)

Может следующим шагом работа с БД (мускул прежде всего), потом как подключить руби к веб-серверу (апачу :) ), написать какое-нить несложное приложение, (вывести форму, записать ее в БД и выслать копию на мыло), а уж потом рельсы. Так хоть будет понятно сколько много рельсы делают для нас у себя внутри.
В Java интерфейсы — это хоть какой-то способ реализовать «множественное наследование». Ну, например, у меня есть класс CoolClass и я хочу от него сделать SuperCoolClass, но добавить возможность запускатся в потоке — классический вопрос множественного наследования. В итоге в Java мы наследуемся от CoolClass b реализуем интерфейс Runnable. В Ruby можно наследоваться от CoolClass и за’mixin’ить модуль Runnable (который в отличии от Java не только объявляет сигнатуры методов но и сам код).
Например, когда вы используете строку в качестве ключа хэша, Руби замораживает ее копию и в дальнейшем использует именно ее. Поэтому даже если строка изменится, на ключ это не повлияет.

Что я делаю не так?
>> a = 'one'
=> "one"
>> hash = {a => 1}
=> {"one"=>1}
>> a.frozen?
=> false
Понял:
>> hash.keys[0].frozen?
=> true
Что вы сразу к Рельсам? Например, полезно и проще будет поиграться с Rake или Shoes. Так же начать веб можно с Sinatra — она очень аксентична и гораздо проще. Например, не надо будет сразу объяснять про MVC и ORM.
Вообще, см. Ruby is not Rails.
Sinatra это тоже MVC, ну если точнее то VC:). По-моему лучше рассмотреть какой-нибудь интересный пример, с применением всего изученного.
А почему не рассказать про автоматическое тестирование, сетевые библиотеки, подробнее рассмотреть разнообразные итераторы? Куча тем осталась нераскрытой, а вы торопитесь в Rails.
Как то слабо про примеси рассказали. Например я часто их использую для стандартныйх классов:
class String
    def tab n
        "  "*n+self
    end
end


Теперь у любой строки можно вызывать метод tab:
puts "asdf".tab
То что вы написали — не примесь. Вы просто открыли существующий класс и добавили метод. Примесь, это если:
module StringExtension
  def tab(n)
    ("  " * n) + self
  end
end

class String; include StringExtension; end
или
String.send(:include, StringExtension)
модуль можно подмешать и extend'ом — для инстансов создастся virtual-класс, и методы модуля будут доступны конкретному инстансу, для класса же extend создаст мета-класс, где будет хранить методы класса.
да, отличие примеси от добавления своих слотов в том, что при include создается прокси-класс, который ссылается на модуль (в сам класс ничего не добавляется)
Итак: module.extend и .include, rake, БД, автотестирование, сетевые библиотеки, примеси и, конечно, пример со всем этим. ОК& :) Может еще есть предложения тем?
НЛО прилетело и опубликовало эту надпись здесь
mixin по-русски называется «примесь»
Спасибо, исправил!
Еще было бы очень наглядно писать результаты примеров (хотя бы то что выводится на консоль)
Договорились!
ну руби и в чистом виде тоже интересен, хотя бы его метапрограмминг.
Нового ничего не узнал, но пишите вы здорово — читал с удовольствием, знаю теперь, что давать для быстрого въезда в тему.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории