Skip to content

Instantly share code, notes, and snippets.

@rewinfrey
Forked from JoshCheek/my_struct.rb
Created February 11, 2013 08:43
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 rewinfrey/4753304 to your computer and use it in GitHub Desktop.
Save rewinfrey/4753304 to your computer and use it in GitHub Desktop.
class MyStruct
def self.new(*method_names, &block)
raise ArgumentError, "wrong number of arguments (0 for 1+)" if method_names.empty?
Class.new do
class_eval &block if block
include Enumerable
def initialize(*args)
@attributes = Hash[members.map(&:to_s).zip args]
end
def inspect
"#<struct #{@attributes.map { |key, value| "#{key}=#{value.inspect}"}.join ', '}>"
end
def size
members.size
end
def values
@attributes.values
end
def each(&block)
values.each(&block)
end
def select(&block)
values.select &block
end
def [](key)
key = key.to_s
raise NameError, "no member '#{key}' in struct" unless @attributes.has_key? key
@attributes[key]
end
def []=(key, value)
key = key.to_s
raise NameError, "no member '#{key}' in struct" unless @attributes.has_key? key
@attributes[key] = value
end
define_method :members do
method_names
end
method_names.each do |method_name|
raise TypeError, "#{method_name} is not a symbol" unless method_name.kind_of? Symbol
define_method method_name do
@attributes[method_name.to_s]
end
define_method "#{method_name}=" do |arg|
@attributes[method_name.to_s] = arg
end
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment