Skip to content

Instantly share code, notes, and snippets.

@ahoward
Created May 8, 2014 19:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ahoward/e09effe88176fe33a8aa to your computer and use it in GitHub Desktop.
Save ahoward/e09effe88176fe33a8aa to your computer and use it in GitHub Desktop.
class Model
def Model.new(*args, &block)
allocate.instance_eval do
@attributes = {}
initialize(*args, &block)
self
end
end
attr(:attributes)
def initialize(params = {})
params.each do |key, val|
@attributes[key.to_s] = val
end
@_in_method_missing = false
end
def method_missing(method, *args, &block)
super if @_in_method_missing
@_in_method_missing = true
begin
match, key, op = /^([^=?]+)([=?]?)$/.match(method.to_s).to_a
case
when op == '='
val = args.shift
attributes[key] = val
when op == '?'
attributes.has_key?(key)
else
if attributes.has_key?(key)
attributes[key]
else
super
end
end
ensure
@_in_method_missing = false
end
end
def inspect(*args, &block)
"#{ type }(#{ attributes.inspect(*args, &block) })"
end
def type
self.class.name
end
def serialize
attributes.map{|k,v| [k,v].join('=')}.join(', ')
end
end
class A < Model
end
class B < Model
end
a = A.new(:x => 0, :y => 1)
p a
p a.x
p a.y
a.x = 40
a.y = 2
p a.x
p a.y
p a.foobar?
puts
b = B.new(:x => 0, :y => 1)
p b
p b.x
p b.y
__END__
~> ruby model.rb
A({"x"=>0, "y"=>1})
0
1
40
2
false
B({"x"=>0, "y"=>1})
0
1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment