Upload
digital-natives
View
322
Download
2
Embed Size (px)
DESCRIPTION
budapest ruby meetup, 10/2013 Tamas Tompa
Citation preview
Basics of MetaprogrammingTamás Tompa (Digital Natives)
Budapest Ruby Meetup 2013
02/10/2013
Thursday, October 3, 13
“Metaprogramming is writing code that writes code.”
Thursday, October 3, 13
what for?§ examples
§ writing a wrapper§ DSL (domain specific language)§ keep your code DRY§ extend core ruby classes
Thursday, October 3, 13
runtime§ static vs dynamic metaprogramming§ everything is object (even classes)§ code introspection
Thursday, October 3, 13
well known example§ ActiveRecord::Base
§ reads the schema at runtime§ discovers fields§ conventions
Thursday, October 3, 13
monkey patching§ monkey patch is a way to extend or
modify the run-time code of dynamic languages without altering the original source code
§ can be dangerous§ always carefully check the existing
methods
Thursday, October 3, 13
basicsobj = MyClass.newobj.class # => MyClass
"hello".class # => StringString.class # => Class
obj.instance_variables # => [:@v]
obj.methods.grep(/my/) # => [:my_method]
Class.instance_methods(false)
Thursday, October 3, 13
basics# ignore inherited methodsClass.instance_methods(false)
String.superclass # => ObjectObject.superclass # => BasicObjectBasicObject.superclass # => nil
# module and kernelD.ancestors # => [D, C, M, Object, Kernel, BasicObject]
Thursday, October 3, 13
“Classes themselves are nothing but objects.”
Thursday, October 3, 13
object model
Thursday, October 3, 13
dynamic methodsclass MyClass
define_method :my_method do |my_arg|
my_arg * 3
end
end
obj = MyClass.new
obj.my_method(2) # => 6
obj.send(:my_method, 2) # => 6
Thursday, October 3, 13
generating methodsclass Computer
def initialize(computer_id, data_source)
end
def self.define_component(name)
define_method(name) do
info = @data_source.send "get_#{name}_info" , @id
price = @data_source.send "get_#{name}_price" , @id
end
end
define_component :mouse
define_component :cpu
end
Thursday, October 3, 13
method missingclass Lawyer
def method_missing(method, *args)
puts "You called: #{method}(#{args.join(', ')})"
puts "(You also passed it a block)" if block_given?
end
end
bob = Lawyer.new
bob.talk_simple('a' , 'b' ) do
# a block
end
You called: talk_simple(a, b)
(You also passed it a block)
Thursday, October 3, 13
http://pragprog.com/book/ppmetr/metaprogramming-ruby
Thursday, October 3, 13
We’re hiring!http://digitalnatives.hu/jobs
Thursday, October 3, 13