Ruby - Dynamically Add Property to Class (At Runtime)

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



Leave a reply



Submit