basics of metaprogramming in ruby

Post on 16-May-2015

311 Views

Category:

Technology

2 Downloads

Preview:

Click to see full reader

DESCRIPTION

budapest ruby meetup, 10/2013 Tamas Tompa

TRANSCRIPT

Basics of MetaprogrammingTamás Tompa (Digital Natives)

tamas.tompa@digitalnatives.hu

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

top related