List of Ruby Metaprogramming methods?
Here is the top answer from this page :
Method-related hooks
method_missing
method_added
singleton_method_added
method_removed
singleton_method_removed
method_undefined
singleton_method_undefined
Class & Module Hooks
inherited
append_features
included
extend_object
extended
initialize_copy
const_missing
Marshalling Hooks
marshal_dump
marshal_load
Coercion Hooks
coerce
induced_from
to_xxx
Also, check this blog post for explanations and sample code for many of these methods.
Ruby: metaprogramming methods based in model attribute
You can define singleton methods (per-object methods).
def order
orders.split(' ').map{|o| send(o)}.compact.each do |o|
singleton_class.send(:define_method, o) do
send(o).to_s
end
end
end
But as you can see, this only messes up your code. So don't abuse metaprogramming, use it wisely.
How to get a list of methods defined in a subclass in Ruby?
Try MyAwesomeSubclass.instance_methods(false)
? I believe that's what you're looking for...
Define method parameters for meta programming in Ruby
Try passing an array or dictionary.
UPDATE:
if condition1
class_eval <<-EVAL
def #{"my_method"}(arg1)
end
EVAL
else
class_eval <<-EVAL
def #{"my_method"}
end
EVAL
end
UPDATE2:
if condition1
self.instance_eval <<-EVAL
def #{"my_method"}(arg1)
end
EVAL
else
self.instance_eval <<-EVAL
def #{"my_method"}
end
EVAL
end
UPDATE3:
# or
self.instance_eval("def method1(arg1) puts 'hellowa' + arg1.to_s; end")
self.instance_eval("def method2() puts 'hellowa2'; end")
# and then
method1(33) # => hellowa33
method2 # => hellowa2
use metaprogramming to surround methods in a class
i guess this solution should help:
class Foo
def initialize
(self.methods - Object.methods).each do |method|
# we need to make alias for method
self.class.send(:alias_method, "#{method}_without_callback", method)
# save method params, and destroy old method
params = self.method(method).parameters.map(&:last).join(',')
self.class.send(:undef_method, method)
# creating new method with old name, and pass params to this
eval("
self.class.send(:define_method, method) do |#{params}|
puts 'Call_before'
self.send('#{method}_without_callback', #{params})
puts 'Call_after'
end
")
end
end
def say_without_param
puts "Hello!"
end
def say_hi(par1)
puts "Hi, #{par1}"
end
def say_good_bye(par1, par2)
puts "Good bye, #{par1} #{par2}"
end
end
So when we create an object, after initialization there will be created alias methods, destroyed old methods, and new methods with call_backs will be created;
Usage example:
obj = Foo.new
obj.say_without_param # => Call_before
Hello!
Call_after
obj.say_hi('Johny') # => Call_before
Hi, Johny
Call_after
obj.say_good_bye('mr.', 'Smith') => Call_before
Good bye, mr. Smith
Call_after
Ruby: Metaprogramming methods from a hash
Assuming that your model is processed and stored in a hash of hashes, then you can use method_missing to implement your scheme. An extremely rough sketch of this is:
class Attributes {
def init(*args) {
@hash = # ....
}
def method_missing(symbol, *args)
result = @hash[symbol]
if (result && args.length) {
return result[args[0]]
}
return result
}
}
Understanding ruby metaprogramming using method_added to overwrite instance methods dynamically
Trace::works as follows: set self to the context that exists within the class definition using instance_eval. Therefore the scope(?) is
modified to how it would be within that class definition.
Using instance eval you evaluate the block with self bound to the object, which in this case will be the class that is including the module. (I.e. the culprit). Just for clarity, there is a difference between:
o = Object.new
o.instance_eval do
puts self
end
and
class Foo < Object end
Foo.instance_eval do puts self end
Answer: So yes you are correct in this assumption!
Then we set method_object to instance_method(meth) which will get the original method that will added. Since instance_method does not
have an explicit receiver, it will default to self which will be the
same as the context of being within the class definition?
Yes, you are correct in your assumption. Do note that, with asking:
culprit.instance_methods(false) => [:someselector, :someotherselector]
And calling instance method in this context is indeed the same as calling self.instance_method.
This method is unbound, so we must bind it to the current context
using bind(self) so it has the same context as it would originally?
Yes. When you get a method in the way defined in the trace module, you get an unbound method object which can be bound again as described.
If you want to dive into Ruby's metaprogramming, I do recommend the following book: http://pragprog.com/book/ppmetr/metaprogramming-ruby it explains all the gritty details behind Ruby's object system, mixins, blocks and anything you can imagine.
Metaprogramming - multiple methods
Its hard to tell because you don't say what class we are "in". I'm guessing we're in Item
, but I am a little unclear why you have item = nil
item = nil
I presume is obfuscating a method by the same name for your instance variable @item.
Another way to do it would be to call the method you defined above.
E.G
define_method "#{item_name}_id" do
self.send(item_name).id
end
Related Topics
How to Host a Rails Web Application
Zip Up All Paperclip Attachments Stored on S3
Are There "Rules" for Ruby Syntactic Sugar
"Ruby.Exe Is Not Recognized as an Internal or External Command" in Windows 7
Date Range Facets with Sunspot in Ruby on Rails
Using Each_With_Index with Map
How to Replicate Class_Inheritable_Accessor's Behavior in Rails 3.1
How to Connect to a Mongodb from Ruby Code
How to Make a Custom Environment in Rails a Default Environment
Text_Field_With_Auto_Complete Inside Form_For
Rvm Install 1.9.2 Fails When Running Autoconf
Gem Install Rails Does Not Install Rails
Os X Mavericks Install Rvm Warning
Heroku Rails Rake Task to Sync Production & Local Db
How to Send Message to All Client Except Sender in Rails/Actioncable
How to Use Your Own MySQL Database Server with Heroku
Simulating Race Conditions in Rspec Unit Tests
Ruby 'split': Invalid Byte Sequence in Utf-8 (Argumenterror)