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

Weitere ähnliche Inhalte

PDF
An Introduction to Ruby
PDF
Devs@Home - Einführung in Go
PDF
PPTX
Prototype 1.7
PDF
Funktionales Programmieren mit Clojure
PDF
T2 s4 javascriptfuerfortgeschrittene
PDF
Ein Gopher im Netz
PDF
P6oo
An Introduction to Ruby
Devs@Home - Einführung in Go
Prototype 1.7
Funktionales Programmieren mit Clojure
T2 s4 javascriptfuerfortgeschrittene
Ein Gopher im Netz
P6oo

Was ist angesagt? (8)

PDF
Scalaz introduction for Java programmers
PDF
Ruby is Magic - Episode #7: Closures
PDF
C Sharp Einfuehrung Teil 2
PDF
Einführung in die funktionale Programmierung mit Clojure
PDF
Perl 5 Quiz Chemnitz Edition
PPT
Die freie Programmiersprache Python
PDF
C Sharp Einfuehrung Teil 1
KEY
Dependency injection
Scalaz introduction for Java programmers
Ruby is Magic - Episode #7: Closures
C Sharp Einfuehrung Teil 2
Einführung in die funktionale Programmierung mit Clojure
Perl 5 Quiz Chemnitz Edition
Die freie Programmiersprache Python
C Sharp Einfuehrung Teil 1
Dependency injection
Anzeige

Andere mochten auch (6)

PDF
02 bedrifter og bank id bergen 2012
DOC
my11
PPT
lukisan teknik
PDF
Consociate Dansig Brochure
PPTX
인터넷교회_주의뜰
PPTX
Windows phone 7 Introduction
02 bedrifter og bank id bergen 2012
my11
lukisan teknik
Consociate Dansig Brochure
인터넷교회_주의뜰
Windows phone 7 Introduction
Anzeige

Ähnlich wie Metaprogrammierung mit Ruby (20)

PDF
Ruby und Rails für .NET Entwickler
PDF
Upgrading Puppet CommitterConf Essen 2014
KEY
Objektorientierte Programmierung mit extbase und fluid
PDF
Perl 5.20: Feature, Kultur, Module, Werkzeuge
PDF
Testing tools
PDF
Skalierbare Anwendungen mit Google Go
PDF
WordPress - eigene Plugins erstellen
PDF
Web Entwicklung mit PHP - Teil 2
PDF
Office-Programmierung mit VBA
PDF
FLOW3-Workshop F3X12
PPTX
Creasoft - Windows powershell
KEY
Ruby on Rails SS09 04
KEY
Ruby on Rails SS09 03
PDF
Vortrag Dirk Weil Gute zeilen, schlechte Zeilen auf der JAX 2012
PDF
WordCamp Köln Filter, Actions, Hooks - was zum Geier ist das?
PDF
Themes – Wieso, Weshalb, Warum!?
PDF
Perl Renaissance Reloaded
PDF
PHP mit Paul Bocuse
PDF
Javascript done right
PDF
Testing untestable code - Herbstcampus12
Ruby und Rails für .NET Entwickler
Upgrading Puppet CommitterConf Essen 2014
Objektorientierte Programmierung mit extbase und fluid
Perl 5.20: Feature, Kultur, Module, Werkzeuge
Testing tools
Skalierbare Anwendungen mit Google Go
WordPress - eigene Plugins erstellen
Web Entwicklung mit PHP - Teil 2
Office-Programmierung mit VBA
FLOW3-Workshop F3X12
Creasoft - Windows powershell
Ruby on Rails SS09 04
Ruby on Rails SS09 03
Vortrag Dirk Weil Gute zeilen, schlechte Zeilen auf der JAX 2012
WordCamp Köln Filter, Actions, Hooks - was zum Geier ist das?
Themes – Wieso, Weshalb, Warum!?
Perl Renaissance Reloaded
PHP mit Paul Bocuse
Javascript done right
Testing untestable code - Herbstcampus12

Metaprogrammierung mit Ruby