Skip to content

Instantly share code, notes, and snippets.

@davidbella
Created October 10, 2013 13:37
Show Gist options
  • Star 40 You must be signed in to star a gist
  • Fork 7 You must be signed in to fork a gist
  • Save davidbella/6918455 to your computer and use it in GitHub Desktop.
Save davidbella/6918455 to your computer and use it in GitHub Desktop.
Ruby: Dynamic meta-programming to create attr_accessor like methods on the fly
class Person
def initialize(attributes)
attributes.each do |attribute_name, attribute_value|
##### Method one #####
# Works just great, but uses something scary like eval
# self.class.class_eval {attr_accessor attribute_name}
# self.instance_variable_set("@#{attribute_name}", attribute_value)
##### Method two #####
# Manually creates methods for both getter and setter and then
# sends a message to the new setter with the attribute_value
self.class.send(:define_method, "#{attribute_name}=".to_sym) do |value|
instance_variable_set("@" + attribute_name.to_s, value)
end
self.class.send(:define_method, attribute_name.to_sym) do
instance_variable_get("@" + attribute_name.to_s)
end
self.send("#{attribute_name}=".to_sym, attribute_value)
end
end
end
@ismail44
Copy link

This just saved me FOREVER!! Thank you!

@texpert
Copy link

texpert commented Oct 5, 2016

Thanks, @davidbella, it's awesome!

Have expanded with methods for creating accessors on other entities - https://gist.github.com/texpert/38f480ed2647f65db5a22f3f98c51fc8

@msimonborg
Copy link

This is awesome, using this and giving you attribution in my documentation. Thank you!

@ievaji
Copy link

ievaji commented Feb 27, 2022

this was super helpful, thx! :)

@hadaromash
Copy link

Helped me as well! Thanks!

@pangui
Copy link

pangui commented Sep 22, 2023

Thank you @davidbella! It's an excellent reference to dinamically handle json columns as regular attributes. I just posted an example here:

https://gist.github.com/pangui/28b45c3601395ef52df649a7ef84388b

The gist can also be adapted for Rails ApplicationRecord models via ActiveSupport::Concern

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment