Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

It's like a "shadow class" that's unique to an instance of something. No written description of this concept ever really 'clicked' for me, personally, so maybe an example will help. Here's a class with a single method `:hello` that will simultaneously increment a counter on its class and on its singleton_class/eigenclass/metaclass:

  irb:1* my_class = Class.new do
  irb:2*   def hello
  irb:2*     "I've counted #{self.class.instance_variable_set(:@count, (self.class.instance_variable_get(:@count) || 0) + 1)} of #{self.class}… " +
  irb:2*     "but only #{self.singleton_class.instance_variable_set(:@count, (self.singleton_class.instance_variable_get(:@count) || 0) + 1)} of #{self.singleton_class}!"
  irb:1*   end
  irb:0> end
  irb:0> foo = my_class.new
  irb:0> bar = my_class.new

Then if we send :hello a few times to each instance you can see how it behaves:

  irb:0> foo.hello
  => "I've counted 1 of #<Class:0x0000561efb9d8238>… but only 1 of #<Class:#<#<Class:0x0000561efb9d8238>:0x0000561efbaa8488>>!"
  irb:0> bar.hello
  => "I've counted 2 of #<Class:0x0000561efb9d8238>… but only 1 of #<Class:#<#<Class:0x0000561efb9d8238>:0x0000561efb9d7040>>!"


  irb:0> foo.hello
  => "I've counted 3 of #<Class:0x0000561efb9d8238>… but only 2 of #<Class:#<#<Class:0x0000561efb9d8238>:0x0000561efbaa8488>>!"
  irb:0> bar.hello
  => "I've counted 4 of #<Class:0x0000561efb9d8238>… but only 2 of #<Class:#<#<Class:0x0000561efb9d8238>:0x0000561efb9d7040>>!"


  irb:0> foo.hello
  => "I've counted 5 of #<Class:0x0000561efb9d8238>… but only 3 of #<Class:#<#<Class:0x0000561efb9d8238>:0x0000561efbaa8488>>!"
  irb:0> foo.hello
  => "I've counted 6 of #<Class:0x0000561efb9d8238>… but only 4 of #<Class:#<#<Class:0x0000561efb9d8238>:0x0000561efbaa8488>>!"
  irb:0> foo.hello
  => "I've counted 7 of #<Class:0x0000561efb9d8238>… but only 5 of #<Class:#<#<Class:0x0000561efb9d8238>:0x0000561efbaa8488>>!"
  irb:0> bar.hello
  => "I've counted 8 of #<Class:0x0000561efb9d8238>… but only 3 of #<Class:#<#<Class:0x0000561efb9d8238>:0x0000561efb9d7040>>!"

For a real-world example of how this can be useful, I use this pattern in my Jekyll multimedia toolbox to handle the specifics of any certain type of media file (e.g. images, videos, audio, etc). I defined separate Modules for separate media_type handling, a single instance will detect the media_type of its associated file (from the file extension or filemagic), then the instance will differentiate itself by Module#prepend-ing the media_type-specific Module to the instance's `singleton_class`. Then the next instance for the next possible-different-type media file has a clean undifferentiated base to start from and the process can repeat: https://github.com/okeeblow/DistorteD/blob/master/DistorteD-...


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: