Sha256: 8e1e9fe477512b7db7f188db78bde1394759a974ca37b65d46743e1add6e60a2

Contents?: true

Size: 1.51 KB

Versions: 1

Compression:

Stored size: 1.51 KB

Contents

#
# http://en.wikipedia.org/wiki/Prototype-based_programming
#

class Prototype
  class << self
    def new proto = Object, *a, &b
      proto = proto.protoclass unless Class === proto

      c = Class.new proto

      c.module_eval do
        define_method(:protoclass) do
          c
        end
      end

      c.module_eval <<-code
        class << self
          def method_missing m, *a, &b
            ivar = "@%s" % m
            if a.size == 0
              if defined? ivar
                instance_variable_get ivar
              else
                super
              end
            elsif a.size == 1
              instance_variable_set ivar, a.shift
              attr_accessor m
            else
              super
            end
          end
        end
      code

      c.module_eval &b if b

      table =
        c.instance_variables.inject({}) do |t,ivar|
          value = 
            c.instance_eval do
              begin
                instance_variable_get ivar
              ensure
                remove_instance_variable ivar
              end
            end
            t.update ivar => value
        end

      c.const_set 'PROTOTABLE', table

      c.module_eval <<-code
        def initialize(*a, &b)
          PROTOTABLE.each do |ivar, value|
            instance_variable_set ivar, value
          end
          super
        end
      code

      obj = c.new *a 

      obj
    end

    alias_method "exnihilo", "new"
    alias_method "ex_nihilo", "new"
    alias_method "clone", "new"
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
prototype-0.0.0 prototype.rb