Skip to content

Instantly share code, notes, and snippets.

@pmarreck
Created August 30, 2012 15:36
Show Gist options
  • Save pmarreck/3531135 to your computer and use it in GitHub Desktop.
Save pmarreck/3531135 to your computer and use it in GitHub Desktop.

Revisions

  1. pmarreck created this gist Aug 30, 2012.
    70 changes: 70 additions & 0 deletions ruby_object_quick_initialization.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,70 @@

    # Some code that lets you quickly erect objects and their attributes with a params hash

    class InvalidAutoInitializeParamError < StandardError; end

    class Object
    class << self
    alias new_without_auto_initialize new
    def new_with_auto_initialize(*args,&block)
    a1 = args.first
    o = new_without_auto_initialize
    if a1.class==Hash
    if o.respond_to?(:initialize_with_hash)
    a1.keys.each do |k|
    setter = (k.to_s << '=').to_sym
    if o.respond_to? k || o.respond_to?(setter) # for now, only allow keys that have accessors
    if o.respond_to?(setter)
    o.send(setter, a1[k])
    else
    o.instance_variable_set("@#{k}".to_sym, a1[k])
    end
    else # don't allow it
    raise InvalidAutoInitializeParamError, "The auto initialize parameter '#{k}' is not allowed for this object"
    end
    end
    if o.method(:initialize_with_hash).arity >= 1
    o.initialize_with_hash(*args, &block)
    else
    o.initialize_with_hash(&block)
    yield o if block_given?
    end
    end
    end
    o
    end
    alias new new_with_auto_initialize
    end
    end

    class Class
    def initialize_with_hash
    self.send(:define_method, :initialize_with_hash){}
    end
    end

    class A
    attr_reader :this, :that
    def initialize_with_hash
    p instance_variables
    end
    end

    class B
    attr_accessor :whoa_dude
    initialize_with_hash
    end

    a = A.new({this: 5, that: 10}){ |a| p a }

    b = B.new(whoa_dude: 'yeah')

    p b

    #=> [:@this, :@that]
    #=> #<A:0x007ff6c2884698 @this=5, @that=10>
    #=> #<B:0x007ff6c2884288 @whoa_dude="yeah">

    a = A.new({this: 5, that: 10, those: 7})

    #=> The auto initialize parameter 'those' is not allowed for this object (InvalidAutoInitializeParamError)