Skip to content

Instantly share code, notes, and snippets.

@thiagoa
Created May 10, 2017 11:17
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 thiagoa/43f46b9b995f1412bc5a28addbcb782d to your computer and use it in GitHub Desktop.
Save thiagoa/43f46b9b995f1412bc5a28addbcb782d to your computer and use it in GitHub Desktop.
class HStruct
def self.new(*members, defaults: {}, &block)
klass = Class.new do
@members = members
@defaults = defaults
class << self
attr_reader :members, :defaults
end
attr_reader(*members)
def initialize(attrs = {})
invalid_members = attrs.keys - self.class.members
fail "No members #{invalid_members} in HStruct" if invalid_members.any?
self.class.members.each do |key|
value = attrs[key] || self.class.defaults[key]
instance_variable_set :"@#{key}", value
end
end
def ==(other)
to_h == other.to_h
end
def to_h
self.class.members.map { |key| [key, public_send(key)] }.to_h
end
def inspect
contents = self.class.members
.map { |key| %{#{key}="#{public_send(key).to_s.gsub('"', '\"')}"} }
.join(' ')
"#<hstruct #{self.class.name} #{contents}>"
end
end
klass.class_eval(&block) if block_given?
klass
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment