Metaprogrammierung mit Ruby
Upcoming SlideShare
Loading in...5
×
 

Metaprogrammierung mit Ruby

on

  • 1,763 views

 

Statistics

Views

Total Views
1,763
Views on SlideShare
1,762
Embed Views
1

Actions

Likes
2
Downloads
3
Comments
0

1 Embed 1

http://a0.twimg.com 1

Accessibility

Categories

Upload Details

Uploaded via as Apple Keynote

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Metaprogrammierung mit Ruby Metaprogrammierung mit Ruby Presentation Transcript

  • Metaprogrammierung Dario Rexin
  • Agenda • Was ist Metaprogrammierung • Ruby Object Model • Open Classes • Methoden in Ruby • Hooks in Ruby • Die Zukunft
  • Was ist Metaprogrammierung View slide
  • 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 View slide
  • 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