How to Dynamically Create Instance Methods at Runtime

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

How can I dynamically create class methods for a class in python

You can dynamically add a classmethod to a class by simple assignment to the class object or by setattr on the class object. Here I'm using the python convention that classes start with capital letters to reduce confusion:

# define a class object (your class may be more complicated than this...)
class A(object):
pass

# a class method takes the class object as its first variable
def func(cls):
print 'I am a class method'

# you can just add it to the class if you already know the name you want to use
A.func = classmethod(func)

# or you can auto-generate the name and set it this way
the_name = 'other_func'
setattr(A, the_name, classmethod(func))

Add ruby class methods or instance methods dynamically

Here's something re-worked to use class methods:

class B
def self.before_method
puts "before method"
end

def self.run(method)
define_singleton_method(method) do
before_method
puts "method #{method}"
end
end
end

Update: Using define_singleton_method from Ruby 1.9 which properly assigns to the eigenclass.

define_method: How to dynamically create methods with arguments

If I understand your question correctly, you want something like this:

class Product
class << self
[:name, :brand].each do |attribute|
define_method :"find_by_#{attribute}" do |value|
all.find {|prod| prod.public_send(attribute) == value }
end
end
end
end

(I'm assuming that the all method returns an Enumerable.)

The above is more-or-less equivalent to defining two class methods like this:

class Product
def self.find_by_name(value)
all.find {|prod| prod.name == value }
end

def self.find_by_brand(value)
all.find {|prod| prod.brand == value }
end
end

Create instance of class known at runtime in Swift

This cannot be done purely in Swift. You can only do this by creating the "class instance by name creator" in Objective C and calling this code from Swift.

For more information you can read this article.
http://ijoshsmith.com/2014/06/05/instantiating-classes-by-name-in-swift/

And check out this github repo
https://github.com/ijoshsmith/swift-factory

Dynamically Create Instance Method in PHP

You are assigning the anonymous function to a property, but then try to call a method with the property name. PHP cannot automatically dereference the anonymous function from the property. The following will work

class Foo{

function __construct() {
$this->sayHi = create_function( '', 'print "hi";');
}
}

$foo = new Foo;
$fn = $foo->sayHi;
$fn(); // hi

You can utilize the magic __call method to intercept invalid method calls to see if there is a property holding a callback/anonymous function though:

class Foo{

public function __construct()
{
$this->sayHi = create_function( '', 'print "hi";');
}
public function __call($method, $args)
{
if(property_exists($this, $method)) {
if(is_callable($this->$method)) {
return call_user_func_array($this->$method, $args);
}
}
}
}

$foo = new Foo;
$foo->sayHi(); // hi

As of PHP5.3, you can also create Lambdas with

$lambda = function() { return TRUE; };

See the PHP manual on Anonymous functions for further reference.



Related Topics



Leave a reply



Submit