e x p r e s s i c a

ruby on rails, business and technicalities

No public Twitter messages.

  • RSS
  • Facebook
  • Twitter
  • Linkedin

class

Doing meta-programming in ruby gives all new ways of getting closer to ruby. There are a lots of Ruby Idioms that attracted a lots of programmers to fall in love with Ruby-Lang. class << self; self; end is a ruby idiom which gives the Big Picture of coding-less and producing-more by providing the way to add an anonymous class to any class which is an instance of class Class. And singleton class can be implemented to any class which will be equally good as implementing it on any object and the reason is that every class that we define with class is again an instance of a class Class. And the beauty is…
[source:ruby]
“string”.class # => String
“string”.class.class # => Class
“string”.class.class.class # => Class
“string”.class.class.superclass # => Module
“string”.class.class.superclass.class # => Class
“string”.class.class.superclass.superclass # => Object
“string”.class.class.superclass.superclass.class # => Class
“string”.class.class.superclass.superclass.superclass # => nil
[/source]

class << self; self; end
Lets try what exactly this idiom returns
[source:ruby]
class A
puts self
puts(class << self; self; end)
end
# => A
# => # <Class:A>
[/source]

As it is cleared from the output that inside the class A, self is reflecting the class A itself whereas class << self; self; end is <Class:A>, so what is the exact difference ?
Lets exemplify it…
[source:ruby]
class A

self.module_eval do
define_method :wish do
puts “hello instance method”
end
end

(class << self; self; end).module_eval do
define_method :wish do
puts “hello class method”
end
end

end

A.wish # => hello class method
A.new.wish # => hello instance method

class B

self.module_eval do
define_method :wish do
puts “hello instance method”
end
end

end

B.new.wish # => hello instance method
B.wish # => undefined method `wish’ for B:Class (NoMethodError)

[/source]

I suppose that it is clear now, in case if it is not than look at this… The following code will do exactly same as above but the class method wish will be available to all classes or we can say to all instances of class Class

[source:ruby]

class Class

self.module_eval do
define_method :wish do
puts “hello — this is class method for instance of class Class”
end
end

end

class A

self.module_eval do
define_method :wish do
puts “hello instance method”
end
end

end

A.wish # => hello — this is class method for instance of class Class
A.new.wish # => hello instance method

class B

self.module_eval do
define_method :wish do
puts “hello instance method”
end
end

end

B.wish # => hello — this is class method for instance of class Class
B.new.wish # => hello instance method

[/source]

4 Responses so far.

  1. gaurav says:

    Great code sur.
    Seems like it will take some time to understand. :)

  2. sur says:

    Thanks,
    I think just reading it again will clear the idea :)

  3. John Tam says:

    I did some practice by following you to make the concepts clear in my mind.
    Thanks for clarify these.


Sponsors