Ruby - dynamically add property to class (at runtime)
The method_missing
approach would work, but if you're going to use the accessors a lot after adding them, you might as well add them as real methods, like this:
class Client
def add_attrs(attrs)
attrs.each do |var, value|
class_eval { attr_accessor var }
instance_variable_set "@#{var}", value
end
end
end
This will make them work like normal instance variables, but restricted to just one client
.
Dynamically add a class to a module in Ruby
You may add a class for dynamically named module like in the following example:
app = Object.const_set('CoolModule', Module.new)
Object.const_get('CoolModule').
const_set('Application', Class.new(Rails::Application) do
config.blabla = 2
end)
If you have access to app
object at point of call, it may replace Object.const_get('CoolModule')
expression, of course.
Module.module_eval
suggests itself but it unfortunately does not do scoped lookup in its block form. It does it in the string argument form, but I'd discourage use of evals on strings.
Ruby - How to set value for dynamic attribute in class
You should call
a.send "#{attr}=", 1
a.save!
Dynamic properties in ruby class
class Example
def value
"This is property!"
end
end
class Test
def check
Example.new
end
end
test = Test.new
puts test.check.value # This is property!
Set Attribute Dynamically of Ruby Object
Use send:
def set_property(obj, prop_name, prop_value)
obj.send("#{prop_name}=",prop_value)
end
More elegant way of setting an object attribute dynamically from string in Ruby
You can do
[:@web, :@mobile, :@accessible].each do |stylesheet|
@theme.instance_variable_set(stylesheet, "some dynamic value"))
end
This saves the string concatenation and string->symbole conversion, so theoretically it's should be a bit faster.
Dynamically added hash properties to Rails Model instance object?
This is the attribute setter shortcut as explained here. It is pretty much equivalent to:
@item.attributes[:visited] = true
How to dynamically create instance methods at runtime?
I'm particularly fond of using method_missing
, especially when the code you want to use is very similar across the various method calls. Here's an example from this site - whenever somebody calls x.boo
and boo
doesn't exist, method_missing is called with boo
, the arguments to boo
, and (optionally) a block:
class ActiveRecord::Base
def method_missing(meth, *args, &block)
if meth.to_s =~ /^find_by_(.+)$/
run_find_by_method($1, *args, &block)
else
super # You *must* call super if you don't handle the
# method, otherwise you'll mess up Ruby's method
# lookup.
end
end
def run_find_by_method(attrs, *args, &block)
# Make an array of attribute names
attrs = attrs.split('_and_')
# #transpose will zip the two arrays together like so:
# [[:a, :b, :c], [1, 2, 3]].transpose
# # => [[:a, 1], [:b, 2], [:c, 3]]
attrs_with_args = [attrs, args].transpose
# Hash[] will take the passed associative array and turn it
# into a hash like so:
# Hash[[[:a, 2], [:b, 4]]] # => { :a => 2, :b => 4 }
conditions = Hash[attrs_with_args]
# #where and #all are new AREL goodness that will find all
# records matching our conditions
where(conditions).all
end
end
define_method
also looks like it would work for you, but I have less experience with it than method_missing
. Here's the example from the same link:
%w(user email food).each do |meth|
define_method(meth) { @data[meth.to_sym] }
end
Related Topics
How to Convert PDF Files to Images Using Rmagick and Ruby
How to Check If a Variable Is a Number or a String
Aws Elastic Beanstalk - How to Upgrade Existing Environment from Ruby 2.1 to Ruby 2.2
Rspec: How to Stub an Instance Method Called by Constructor
How to Use "Puts" to the Console Without a Line Break in Ruby on Rails
Conditional Key/Value in a Ruby Hash
Finding the Session Id in Rails 3
What Does Post.All.Map(&:Id) Mean
Uninitialized Constant Rake::Dsl in Ruby Gem
Create Array of N Items Based on Integer Value
Repairing Postgresql After Upgrade to Osx Mavericks
Case-Insensitive Array#Include
Do Fixtures Trigger Model Callbacks