Skip to content

Instantly share code, notes, and snippets.

@stefanoc
Created February 17, 2015 21:55
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 stefanoc/c3ebb922465ee69c89e2 to your computer and use it in GitHub Desktop.
Save stefanoc/c3ebb922465ee69c89e2 to your computer and use it in GitHub Desktop.
Computed attributes
module ComputedAttributes
module ClassMethods
def compute(name, components, &block)
getter = -> do
value = instance_variable_get("@_#{name}")
unless value
value = instance_exec(&block)
instance_variable_set("@_#{name}", value)
end
value
end
define_method(name, &getter)
components.each do |attribute|
setter = ->(value) do
instance_variable_set("@_#{name}", nil)
super(value)
end
define_method("#{attribute}=", &setter)
end
end
end
end
class Person < Struct.new(:first_name, :last_name)
extend ComputedAttributes::ClassMethods
compute :full_name, [:first_name, :last_name] { "#{first_name} #{last_name}" }
end
me = Person.new('John', 'Doe')
puts me.full_name
me.first_name = 'Jane'
puts me.full_name
me.last_name = 'Smith'
puts me.full_name
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment