Skip to content

Instantly share code, notes, and snippets.

@edtsech
Created July 30, 2012 11:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save edtsech/3206400 to your computer and use it in GitHub Desktop.
Save edtsech/3206400 to your computer and use it in GitHub Desktop.
Two classes with the same name, but with different obejct_id.
ContentFor = Class.new
x = ContentFor.new
puts x.class.object_id # => 2266662780
# puts x.class.name
ContentFor = Class.new
y = ContentFor.new
puts x.class.object_id # => 2266662780
puts x.class.name # => nil
puts y.class.object_id # => 2266662700
puts y.class.name # => nil
puts ContentFor.object_id # => 2266662700
ContentFor = Class.new
x = ContentFor.new
puts x.class.object_id # => 2266662780
puts x.class.name # => ContentFor
ContentFor = Class.new
y = ContentFor.new
puts x.class.object_id # => 2266662780
puts x.class.name # => ContentFor
puts y.class.object_id # => 2266662700
puts y.class.name # => ContentFor
puts ContentFor.object_id # => 2266662700
class ContentFor < Liquid::Tag
...
end
.....
node.class # => ContentFor
node.class.object_id # => 70174154320900
ContentFor.object_id # => 70174175475880
node.is_a? ContentFor # => false
node.class.name == "ContentFor" # => true
@evtuhovich
Copy link

Удивительно, а можешь из этого сделать маленький какой-нибудь кусочек, подтверждающий идею?

@edtsech
Copy link
Author

edtsech commented Jul 30, 2012

Добавил boom.rb файл. Суть в том, что просто сохраняется ссылка на класс у инстанса.

@evtuhovich
Copy link

А, это тогда объяснимый факт, хотя я был уверен, что нельзя константы переопределять без warning-а

@edtsech
Copy link
Author

edtsech commented Jul 30, 2012

Warning будет

@evtuhovich
Copy link

Проверил - warning есть. Это забавный случай, но не тот, о котором мы в подкасте говорили.

В данном случае стоит сказать ай-яй-яй тому, кто этот код писал, потому что это сознательно вводит в заблуждение тех, кто его использует.

@edtsech
Copy link
Author

edtsech commented Jul 30, 2012

Я согласен. Но не уверен, что в моем приложении именно эта ситуация. Потому что классы в файле boom.rb анонимные, а в моей ситуации в приложении они обычные, то есть по идее должны просто переоткрыться при написании еще раз class ContentFor, ну ты понимаешь :)

@mikdiet
Copy link

mikdiet commented Jul 30, 2012

Модули в руби бывают достижимые (reachable) и недостижимые. Во втором случае метод 'name' модуля помнит имя константы, которая на него ссылалась когда-то, но фактически константа может не существовать или ссылаться на что-то другое

@evtuhovich
Copy link

Ага, идея понятна, надо смотреть конкретный код, чтобы понять, почему такое происходит

@edtsech
Copy link
Author

edtsech commented Jul 30, 2012

@evtuhovich ну или хотя бы иметь ряд предположений почему это может быть, чтобы их проверить

@evtuhovich
Copy link

Никаких идей пока, все, что были проверил - не подходят :-(

@edtsech
Copy link
Author

edtsech commented Jul 30, 2012

Добавил boom2.rb где сохраняется имя константы.

@edtsech
Copy link
Author

edtsech commented Jul 30, 2012

@Mik-die в случае недостижимости помнит?

@mikdiet
Copy link

mikdiet commented Jul 30, 2012

@edtsech, да, вот хороший пример в рельсовых гайдах http://guides.rubyonrails.org/active_support_core_extensions.html#reachable

@edtsech
Copy link
Author

edtsech commented Jul 30, 2012

1.9.3p125 :001 > module M
1.9.3p125 :002?>   end
 => nil 
1.9.3p125 :003 > M.name
 => "M" 
1.9.3p125 :004 > M.reachable?
 => true 
1.9.3p125 :005 > B = Module.new
 => B 
1.9.3p125 :006 > B.name
 => "B" 
1.9.3p125 :007 > B.reachable?
 => true 

@Mik-die Достижимые тоже помнят свое имя.

@edtsech
Copy link
Author

edtsech commented Jul 30, 2012

@Mik-die что можешь сказать кстати по поводу разницы между boom.rb и boom2.rb ? Я незнаю почему в одном случае сохраняется имя в другом нет.

@mikdiet
Copy link

mikdiet commented Jul 30, 2012

Ну достижимые знают свое имя по очевидной причине :)

Я не вижу разницы в двух примерах, и я скопипастил первый пример, и там у меня пишется имя для обоих классов. Может быть показалось, там puts стоит - в консоли он сначала выводит то, что в него передали, а потом nil

@edtsech
Copy link
Author

edtsech commented Jul 30, 2012

Вот мой вывод:

➜  ~  ruby boom.rb 
70320438645840
boom.rb:7: warning: already initialized constant ContentFor
70320438645840

70320438645740
ContentFor
70320438645740
➜  ~  ruby boom2.rb
70305804877520
ContentFor
boom2.rb:7: warning: already initialized constant ContentFor
70305804877520
ContentFor
70305804877380
ContentFor
70305804877380

@edtsech
Copy link
Author

edtsech commented Jul 30, 2012

@Mik-die я просто думал имя как-то зависит от достижимости, раз ты акцентировал внимание на том, что недостижимые помнят имя. Но не суть, теперь понял.

@mikdiet
Copy link

mikdiet commented Jul 30, 2012

Да, вижу, в консоли это не было заметно..
http://codepad.org/gGZzowA9
http://codepad.org/vYznrZoO

Наверное имя как-то лениво определяется.. там си, не хочу смотреть :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment