SlideShare ist ein Scribd-Unternehmen logo
Metaprogrammierung

      Dario Rexin
Agenda
• Was ist Metaprogrammierung
• Ruby Object Model
• Open Classes
• Methoden in Ruby
• Hooks in Ruby
• Die Zukunft
Was ist
Metaprogrammierung
Was ist
Metaprogrammierung
• Writing code, that writes code
• Code zur Laufzeit des Programms
  generieren und evaluieren
• Klassen und Strukturen zur Laufzeit
  verändern
• Metaprogrammierung == Programmierung
Ruby Object Model
Ruby Object Model


        Foo
Ruby Object Model
       Object




        Foo
Ruby Object Model
       Object




        Foo
Ruby Object Model


       Object




        Foo
Ruby Object Model


       Object




        Foo
Ruby Object Model
       Kernel




       Object




        Foo
Ruby Object Model
       Kernel




       Object




        Foo
Ruby Object Model
   Kernel




   Object




    Foo
Ruby Object Model
   Kernel




   Object




    Foo
Ruby Object Model
   Kernel   #Kernel




   Object   #Object




    Foo      #Foo
Open Classes
Open Classes

• Klassen können jederzeit wieder geöffnet
  werden
• Methoden/Variablen können hinzugefügt,
  überschrieben und entfernt werden
Beispiel

class String
  def foo             class String
    “foo”               undef to_s
  end                 end
end
Methoden in Ruby
Methoden in Ruby
Methoden in Ruby
 instance_eval         remove_const

                                        instance_variable_get
      const_set                eval
                                             define_method
   class_eval           undef
                                      send
instance_variable_set
                                             const_get
                alias_method
const

• Object.const_get(:String) => String
• Object.const_set(:Foo, Class.new) => Foo
• Object.remove_const(:Foo) => Bar
const

• Object.const_get(:String) => String
• Object.const_set(:Foo, Class.new) => Foo
• Object.remove_const(:Foo) => Bar #private
instance_variable

• obj.instance_variable_set(:@foo, 8)
• obj.instance_variable_get(:@foo)
• obj.remove_instance_variable(:@foo)
instance_variable

• obj.instance_variable_set(:@foo, 8)
• obj.instance_variable_get(:@foo)
• obj.remove_instance_variable(:@foo)   #private
eval

• evaluiert String im aktuellen Kontext
• Zugriff auf alle Variablen/Methoden möglich
• mit Bedacht einsetzen
eval

while(true) do
 input = gets.sub(/n/, '')
 eval("puts Object.const_get
      ('#{input}'.to_sym).methods")
end
eval
input == String
eval
input == String

   Output:

 try_convert
 allocate
 new
 superclass
 ...
eval
input == String');puts Dir.glob('/*/**');#
eval
input == String');puts Dir.glob('/*/**');#

                Output:
   ...
   /Applications/Address Book.app
   /Applications/App Store.app
   /Applications/AppCleaner.app
   /Applications/Automator.app
   /Applications/Caffeine.app
   ...
May I touch your
   privates?
May I touch your
   privates?

  Object.instance_eval do
     remove_const(:Bar)
  end
May I touch your
   privates?
Object.instance_eval do
   private_methods.each do |m|
      public m
   end
end
define_method

• fügt dem Objekt eine neue Methode hinzu
• Parameter: name, &block
• Block-Parameter: *args
Hooks in Ruby
Hooks in Ruby

• method_added / _removed
• method_missing
• Module#included
method_added

• Aufruf beim Hinzufügen einer Methode
• Parameter: name
• nützlich, wenn man eine Methode mit einer
  anderen umschließen möchte
Beispiel
class Foo
  def self.method_added name
    alias_method “__old_#{name}__”, name
    define_method name do |*args|
      puts “called #{name}”
      self.send(“__old_#{name}__”, *args)
    end
  end
end
method_missing

• Aufruf, wenn keine Methode gefunden wird
• Parameter: name, *args
• dynamische Methoden erstellen
• wird in vielen Libraries benutzt
Beispiel
class Hash
  def method_missing name, *args
    return super(name, *args)
        unless self.include? (name)
    self[name]
  end
end
Beispiel
class Hash
  def method_missing name, *args
    return super(name, *args)
        unless self.include? (name)
    self[name]
  end
end

   {:foo => :bar}.foo # => :bar
Module#included


• Aufruf, wenn Modul inkludiert wird
• Parameter: Klasse, welche das Modul
  inkludiert
Beispiel
module Foo
 def self.included base
  base.extend(ClassMethods)
 end

 module ClassMethods
   #...
 end
end
Die Zukunft
Die Zukunft

• refinements
• machen Monkey Patching sicherer
• nur im Scope gültig
Beispiel
MyGreatMoneyGem:      MyMuchBetterMoneyGem:
 class Fixnum              class Fixnum
   def euro                  def euro
     “#{self} €”               Euro.new(self)
   end                       end
   # usw.                    # usw.
 end                       end
Lösung
MyGreatMoneyGem:      MyMuchBetterMoneyGem:
 module MGMG             module MMBMG
  refine Fixnum do         refine Fixnum do
    def euro                def euro
     “#{self}€”              Euro.new(self)
    end                     end
    # usw.                  # usw.
  end                     end
 end                     end
Anwendung
 class ThisClass        class ThatClass
   using MGMG             using MMBMG

  def self.do_sth        def self.do_sth
    5.euro                 5.euro
  end                    end
 end                    end

MGMG.do_sth # => 5€   MGMG.do_sth # =>
                         #<Euro: 0x0......>
Scopes
using A #global

module Foo
 using B #modulweit

 class Bar
   using C #klassenweit

    def baz
      using D #nur innerhalb der Methode
    end
  end
end
Kein local rebinding
 class Foo
   def bar   module Mod
     baz      refine Foo do
   end          def baz
                 “no baz”
  def baz       end
    “baz”     end
  end        end
 end
Kein local rebinding

   using Mod

   Foo.new.baz # => “no baz”
   Foo.new.bar # => “baz”
Danke für die
Aufmerksamkeit
Links

•   http://yehudakatz.com/2010/11/30/ruby-2-0-
    refinements-in-practice/

•   http://www.rubyinside.com/ruby-refinements-an-
    overview-of-a-new-proposed-ruby-
    feature-3978.html

•   http://timeless.judofyr.net/refinements-in-ruby
Anzeige

Empfohlen

An Introduction to Ruby
An Introduction to Ruby
Jonathan Weiss
 
Devs@Home - Einführung in Go
Devs@Home - Einführung in Go
Frank Müller
 
Ruby, Ruby, Ruby!
Ruby, Ruby, Ruby!
fg.informatik Universität Basel
 
Prototype 1.7
Prototype 1.7
msebel
 
Funktionales Programmieren mit Clojure
Funktionales Programmieren mit Clojure
Dr. Christian Betz
 
T2 s4 javascriptfuerfortgeschrittene
T2 s4 javascriptfuerfortgeschrittene
dominion
 
Ein Gopher im Netz
Ein Gopher im Netz
Frank Müller
 
P6oo
P6oo
lichtkind
 
Scalaz introduction for Java programmers
Scalaz introduction for Java programmers
Bernhard Huemer
 
Ruby is Magic - Episode #7: Closures
Ruby is Magic - Episode #7: Closures
Dirk Breuer
 
C Sharp Einfuehrung Teil 2
C Sharp Einfuehrung Teil 2
DraphonyGames
 
Einführung in die funktionale Programmierung mit Clojure
Einführung in die funktionale Programmierung mit Clojure
Sascha Koch
 
Perl 5 Quiz Chemnitz Edition
Perl 5 Quiz Chemnitz Edition
lichtkind
 
Die freie Programmiersprache Python
Die freie Programmiersprache Python
Andreas Schreiber
 
C Sharp Einfuehrung Teil 1
C Sharp Einfuehrung Teil 1
DraphonyGames
 
Dependency injection
Dependency injection
Mario Müller
 
02 bedrifter og bank id bergen 2012
02 bedrifter og bank id bergen 2012
joivha
 
my11
my11
lennox100
 
lukisan teknik
lukisan teknik
Mohd Ibrahim
 
Consociate Dansig Brochure
Consociate Dansig Brochure
troysmith01
 
인터넷교회_주의뜰
인터넷교회_주의뜰
Eun Hae Song
 
Windows phone 7 Introduction
Windows phone 7 Introduction
Abdullah Muhammad
 
Ruby on Rails SS09 03
Ruby on Rails SS09 03
Daniel Dengler
 
Ruby on Rails SS09 04
Ruby on Rails SS09 04
Daniel Dengler
 
Ruby und Rails für .NET Entwickler
Ruby und Rails für .NET Entwickler
NETUserGroupBern
 
Designpatterns in Ruby
Designpatterns in Ruby
pfleidi
 
Lehmanns Rails Erweitern
Lehmanns Rails Erweitern
jan_mindmatters
 
Ruby - Eine kurze Einführung
Ruby - Eine kurze Einführung
Thomas R. Koll
 
Einstieg In Oop
Einstieg In Oop
flashdev
 
Ruby On Rails Einführung
Ruby On Rails Einführung
Reinhold Weber
 

Weitere ähnliche Inhalte

Was ist angesagt? (8)

Scalaz introduction for Java programmers
Scalaz introduction for Java programmers
Bernhard Huemer
 
Ruby is Magic - Episode #7: Closures
Ruby is Magic - Episode #7: Closures
Dirk Breuer
 
C Sharp Einfuehrung Teil 2
C Sharp Einfuehrung Teil 2
DraphonyGames
 
Einführung in die funktionale Programmierung mit Clojure
Einführung in die funktionale Programmierung mit Clojure
Sascha Koch
 
Perl 5 Quiz Chemnitz Edition
Perl 5 Quiz Chemnitz Edition
lichtkind
 
Die freie Programmiersprache Python
Die freie Programmiersprache Python
Andreas Schreiber
 
C Sharp Einfuehrung Teil 1
C Sharp Einfuehrung Teil 1
DraphonyGames
 
Dependency injection
Dependency injection
Mario Müller
 
Scalaz introduction for Java programmers
Scalaz introduction for Java programmers
Bernhard Huemer
 
Ruby is Magic - Episode #7: Closures
Ruby is Magic - Episode #7: Closures
Dirk Breuer
 
C Sharp Einfuehrung Teil 2
C Sharp Einfuehrung Teil 2
DraphonyGames
 
Einführung in die funktionale Programmierung mit Clojure
Einführung in die funktionale Programmierung mit Clojure
Sascha Koch
 
Perl 5 Quiz Chemnitz Edition
Perl 5 Quiz Chemnitz Edition
lichtkind
 
Die freie Programmiersprache Python
Die freie Programmiersprache Python
Andreas Schreiber
 
C Sharp Einfuehrung Teil 1
C Sharp Einfuehrung Teil 1
DraphonyGames
 
Dependency injection
Dependency injection
Mario Müller
 

Andere mochten auch (6)

02 bedrifter og bank id bergen 2012
02 bedrifter og bank id bergen 2012
joivha
 
my11
my11
lennox100
 
lukisan teknik
lukisan teknik
Mohd Ibrahim
 
Consociate Dansig Brochure
Consociate Dansig Brochure
troysmith01
 
인터넷교회_주의뜰
인터넷교회_주의뜰
Eun Hae Song
 
Windows phone 7 Introduction
Windows phone 7 Introduction
Abdullah Muhammad
 
02 bedrifter og bank id bergen 2012
02 bedrifter og bank id bergen 2012
joivha
 
Consociate Dansig Brochure
Consociate Dansig Brochure
troysmith01
 
인터넷교회_주의뜰
인터넷교회_주의뜰
Eun Hae Song
 
Windows phone 7 Introduction
Windows phone 7 Introduction
Abdullah Muhammad
 
Anzeige

Ähnlich wie Metaprogrammierung mit Ruby (12)

Ruby on Rails SS09 03
Ruby on Rails SS09 03
Daniel Dengler
 
Ruby on Rails SS09 04
Ruby on Rails SS09 04
Daniel Dengler
 
Ruby und Rails für .NET Entwickler
Ruby und Rails für .NET Entwickler
NETUserGroupBern
 
Designpatterns in Ruby
Designpatterns in Ruby
pfleidi
 
Lehmanns Rails Erweitern
Lehmanns Rails Erweitern
jan_mindmatters
 
Ruby - Eine kurze Einführung
Ruby - Eine kurze Einführung
Thomas R. Koll
 
Einstieg In Oop
Einstieg In Oop
flashdev
 
Ruby On Rails Einführung
Ruby On Rails Einführung
Reinhold Weber
 
Ruby on Rails SS09 08
Ruby on Rails SS09 08
Daniel Dengler
 
Typ-sichere DSLs
Typ-sichere DSLs
Werner Keil
 
Ruby is Magic - Episode #8: self
Ruby is Magic - Episode #8: self
Dirk Breuer
 
Genügend gute Gründe, wieso Ruby besser als PHP ist
Genügend gute Gründe, wieso Ruby besser als PHP ist
Daniel Spangenberg
 
Ruby und Rails für .NET Entwickler
Ruby und Rails für .NET Entwickler
NETUserGroupBern
 
Designpatterns in Ruby
Designpatterns in Ruby
pfleidi
 
Lehmanns Rails Erweitern
Lehmanns Rails Erweitern
jan_mindmatters
 
Ruby - Eine kurze Einführung
Ruby - Eine kurze Einführung
Thomas R. Koll
 
Einstieg In Oop
Einstieg In Oop
flashdev
 
Ruby On Rails Einführung
Ruby On Rails Einführung
Reinhold Weber
 
Typ-sichere DSLs
Typ-sichere DSLs
Werner Keil
 
Ruby is Magic - Episode #8: self
Ruby is Magic - Episode #8: self
Dirk Breuer
 
Genügend gute Gründe, wieso Ruby besser als PHP ist
Genügend gute Gründe, wieso Ruby besser als PHP ist
Daniel Spangenberg
 
Anzeige

Metaprogrammierung mit Ruby