Sha256: ac8afd46e219fc22d8278ec79ef2f4794df8cce2c0bc2c6afe8ac847a548935c

Contents?: true

Size: 1.84 KB

Versions: 18

Compression:

Stored size: 1.84 KB

Contents

module Pod4


  ##
  # A little mixin for metaprogramming
  #
  module Metaxing

    ##
    # Return the metaclass (eigenclass) of self.
    #
    def metaclass
      class << self; self; end
    end


    ##
    # Define (or re-define) a class method.
    #
    # Example:
    #     
    #     class Foo
    #       extend Metaxing
    #
    #       class << self
    #         def set_bar(x); define_class_method(:bar) {x}; end
    #       end
    #     end
    #
    #     class MyFoo < Foo; end
    #
    #     Foo.set_bar(23)
    #     puts Foo.bar   # -> 23
    #     puts MyFoo.bar # -> 23
    #
    #     MyFoo.set_bar(42) 
    #     puts Foo.bar   # -> 23
    #     puts MyFoo.bar # -> 42
    # 
    # This example gives us something different from a class attribute @@bar -- the value of which
    # would be shared between Foo and MyFoo.  And different again from an attribute @bar on class
    # Foo, which wouldn't turn up in MyFoo at all. This is a value that has inheritance.
    #
    # And this example shows pretty much the only metaprogramming trick you will find me pulling.
    # It's enough to do a hell of a lot.
    #
    # Note that you need to be very careful what parameters you pass in order to preserve this
    # inheritance: if you pass a reference to something on Foo, you will be sharing it with MyFoo,
    # not just inheriting it. Best to use local variables or dups.
    #
    # ...Well, actually, you aren't getting a method on the class -- these are defined in the
    # class' immediate ancestor, eg, Object. You're getting a method on the eigenclass, which Ruby
    # inserts between the class' ancestor and the class. For all of me I can't see a practical
    # difference when it comes to defining class methods.
    #
    def define_class_method(method, *args, &blk)
      metaclass.send(:define_method, method, *args, &blk)
    end

  end


end

Version data entries

18 entries across 18 versions & 1 rubygems

Version Path
pod4-1.0.1 lib/pod4/metaxing.rb
pod4-1.0.0 lib/pod4/metaxing.rb
pod4-0.10.6 lib/pod4/metaxing.rb
pod4-0.10.5 lib/pod4/metaxing.rb
pod4-0.10.4 lib/pod4/metaxing.rb
pod4-0.10.3 lib/pod4/metaxing.rb
pod4-0.10.2 lib/pod4/metaxing.rb
pod4-0.10.1 lib/pod4/metaxing.rb
pod4-0.10.0 lib/pod4/metaxing.rb
pod4-0.9.3 lib/pod4/metaxing.rb
pod4-0.9.2 lib/pod4/metaxing.rb
pod4-0.9.1 lib/pod4/metaxing.rb
pod4-0.9.0 lib/pod4/metaxing.rb
pod4-0.8.3 lib/pod4/metaxing.rb
pod4-0.8.2 lib/pod4/metaxing.rb
pod4-0.8.1 lib/pod4/metaxing.rb
pod4-0.8.0 lib/pod4/metaxing.rb
pod4-0.7.2 lib/pod4/metaxing.rb