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
Rails 404 Error for Stylesheet or JavaScript Files
Why Do Numeric String Comparisons Give Unexpected Results
Ruby Gem Cucumber Ssl Error and Gem Sources
Rails 3.2 Create a Form That's Used in the Footer of Every Page
Rails: Organizing Models in Subfolders Having Warning: Toplevel Constant a Referenced by B::A
Ruby Range: Operators in Case Statement
Intelligently Generating Combinations of Combinations
How to Pass Value from One Resource to Another Resource in Chef Recipe
Any Ruby Library to Inspect What Are the Arguments That a Certain Methods Take
Elegant Way to Only Show Records If They Exist in Rails Erb
Why Does Trying to Use Grape with Rails Fail with "Uninitialized Constant API"
Flatten a Ruby Array Without Using Built-In 'Flatten' Method
Does 'Upcase!' Not Mutate a Variable in Ruby
Uri::Invalidurierror: Bad Uri(Is Not Uri) Testing Rails Controllers
How to Spec Methods That Exit or Abort
How to Fix Ruby Script Which Fails with Encoding Error: "\Xd8" on Us-Ascii