Skip to content

Instantly share code, notes, and snippets.

@eljojo
Forked from lucaong/README.md
Created February 26, 2014 12:37
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 eljojo/9228776 to your computer and use it in GitHub Desktop.
Save eljojo/9228776 to your computer and use it in GitHub Desktop.

ClosedStruct

A stupidly simple implementation of a kind of "sorta immutable" struct that can be instantiated as conveniently as an OpenStruct but after instantiation it doesn't let me (easily) add fields or mutate them:

guy = ClosedStruct.new( name: "John", age: 23 )

# readers:
guy.name             #=> "John"
guy.age              #=> 23
guy.xxx              #=> NoMethodError: undefined method `xxx'...

# respond_to? and methods work as expected:
guy.respond_to? :age #=> true
guy.methods(false)   #=> [:name, :age]

# in-place modification is prevented, but you can create modified copies with #merge:
guy.name = "Jack"      #=> NoMethodError: undefined method `name='...
guy.merge name: "Jack" #=> a new ClosedStruct instance with name: "Jack", age: 23
class ClosedStruct
def initialize( attr_hash )
attrs = attr_hash.dup
attrs.each do |attr_name, attr_value|
self.define_singleton_method(attr_name) do
attr_value
end
end
self.define_singleton_method(:to_h) do
attrs
end
end
def merge( modified_attrs = {} )
self.class.new to_h.merge( modified_attrs )
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment