class A
  def initialize
    setup_b
    setup_c
  end

  def b_and_c
   "#{@b} and #{@c}"
  end

private
 def setup_b
    @b = 'b'
  end

  def setup_c
    @c = 'c'
  end

  def setup_d
    @d = 'd'
  end
end

a = A.new
a.instance_variable_get("@b") # => "b"
a.instance_variable_get("@c") # => "c"
a.instance_variable_get("@d") # => nil
a = A.new.b_and_c # => "b and c"


Now what I did above is to make a point. initialize allows us to
create some initial setup for new objects, so that when we call a
public method like b_and_c, we can expect certain values back based on
the initialization hook that must occur first. From my understanding,
modules do not have an initialize method, so then how do you simulate
it? Well, I was looking at Rails and notice this:

 class Template
    module Handlers
      autoload :ERB, 'action_view/template/handlers/erb'
      autoload :Builder, 'action_view/template/handlers/builder'
      autoload :Raw, 'action_view/template/handlers/raw'

      def self.extended(base)
        base.register_default_template_handler :erb, ERB.new
        base.register_template_handler :builder, Builder.new
        base.register_template_handler :raw, Raw.new
      end

      @@template_handlers = {}
      @@default_template_handlers = nil

      def self.extensions
        @@template_extensions ||= @@template_handlers.keys
      end

      def register_default_template_handler(extension, klass)
        register_template_handler(extension, klass)
        @@default_template_handlers = klass
      end

     def register_template_handler(extension, handler)
        @@template_handlers[extension.to_sym] = handler
        @@template_extensions = nil
      end

 class Template
    extend Template::Handlers


class LookupContext
   register_detail(:handlers){ Template::Handlers.extensions }


Basically, when ruby loads the Template class (I will assume that it
must be loaded prior to Handlers module or LookupContext class), it
immediately executes a class method, which is called extend, and
passes the module Handlers as the lone argument. What the extend
method does is copy the methods of the module Handlers to the Template
class as class methods. But what else happens is the self.extended
hook is immediately triggered, just as initialize is when you
instantiate a class. We pass our Template class object as the
parameter base. And we call the register_default_template_handler
method (which is now a class method of Template), passing it a
symbol :erb and an instance of ERB, which returns a string from
call(). We in turn call register_template_handler, passing in the same
two arguments. We simply append the key/value pair to the
@@template_handlers class variable, which is a hash data type, and
allows us to add a number of key/value pairs corresponding to
extensions and template types. (e.g. :erb extension corresponding to
an ERB template type). Hence, when we invoke the module method
extensions on the module, it can return a value for the
@@template_handlers class variable, since it was initialized with
values during the hook, prior to the extensions method call.

I have a few questions about this.

1) Is is true to say that the class variables of the module get
initialized prior than the extended hook. Reason why say this is that
the extended hook calls a method that expects the variable to be set
already.

2) Do all the methods of the module get copied over to base (Template
class object) prior to the hook being called? Reason why I say this is
because we call base.register_default_template_handler, where base is
Tempalte object an register_default_template_handler is defined in the
module that gets copied to base as a class method via extend. Hence,
in order for base.register_default_template_handler to work, the
methods must have been copied first.

3) Can anyone tell me what @@template_extensions is for? I dont see
that initialized with a value anywhere other than nil.

thanks for response


-- 
You received this message because you are subscribed to the Google Groups "Ruby 
on Rails: Talk" group.
To post to this group, send email to rubyonrails-talk@googlegroups.com.
To unsubscribe from this group, send email to 
rubyonrails-talk+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to