Расширение классов и экземпляров

У Вас могло быть невидимое отделение, которое показывают через JavaScript, когда страница загружается.

5
задан teleball 8 November 2009 в 17:30
поделиться

2 ответа

obj.extend (модуль) добавляет все методы из модуля в obj . Когда вызывается как String.extend (Greeter) , вы добавляете методы из Greeter в экземпляр Class , который представляет String .

Самый простой способ добавить дополнительные методы экземпляра к существующему классу - это повторно открыть класс. Следующие примеры делают то же самое:

class String
  include Greeter
end

class String
  def ciao
    "Ciao!"
  end
end

Fixnums (а также Symbols, true, false и nil) обрабатываются иначе, чем обычные экземпляры. Два Fixnum с одинаковым значением всегда будут представлены одним и тем же экземпляром объекта. В результате Ruby не позволяет вам расширять их.

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

t = "Test"
t.extend(Greeter)
t.ciao
=> "Ciao!"
2
ответ дан 13 December 2019 в 19:29
поделиться

First question. Why is it that if you extend a class with a new method, and then create an object/instance of that class, you cannot access that method?

Because you extended the String class, so #ciao is a class method and not an instance method.

String.send(:include, Greeter)
x = "foo bar"
x.ciao
# => "Ciao!"

Second part, When I try to extend a Fixnum object, I get an undefined method error. Can someone explain why this works for a string but not a fixnum?

Here's the short answer.

"Fixnums, Symbols, true, nil, and false are implemented as immediate values. With immediate values, variables hold the objects themselves, rather than references to them.

Singleton methods cannot be defined for such objects. Two Fixnums of the same value always represent the same object instance, so (for example) instance variables for the Fixnum with the value "one" are shared between all the "ones" is the system. This makes it impossible to define a singleton method for just one of these."

Off course, you can include/exten the Fixnum class and every Fixnum instance will expose the methods in the Mixin. This is exactly what Rails/ActiveSupport does in order to allow you to write

3.days.ago
1.hour.from_now
9
ответ дан 13 December 2019 в 19:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: