Bücher online kostenlos Kostenlos Online Lesen
Die Programmiersprache Ruby (German Edition)

Die Programmiersprache Ruby (German Edition)

Titel: Die Programmiersprache Ruby (German Edition) Kostenlos Bücher Online Lesen
Autoren: David Flanagan , Yukihiro Matsumoto
Vom Netzwerk:
Block ist.
    #
    class_eval %Q{
     def #{m}(*args, &block)
     synchronized(self) { #{aka}(*args, &block) }
     end
    }
end
end
# Diese globale Methode synchronized kann nun auf drei verschiedene
# Arten verwendet werden.
def synchronized(*args)
# Fall 1: mit einem Argument und einem Block das Objekt
# synchronisieren und den Block ausführen
if args.size == 1 && block_given?
    args[0].mutex.synchronize { yield }
# Fall 2: mit einem Argument, das kein Symbol und kein
# Block ist, einen SynchronizedObject-Wrapper zurückgeben
elsif args.size == 1 and not args[0].is_a? Symbol and not block_given?
    SynchronizedObject.new(args[0])
# Fall 3: bei Aufruf für ein Modul ohne Block Alias-Verkettung der
# genannten Methoden durchführen, um Synchronisation hinzu-
# zufügen oder bei Aufruf ohne Argumente Alias-Verkettung
# der als Nächstes definierten Methode durchführen
elsif self.is_a? Module and not block_given?
    if (args.size > 0) # Die genannten Methoden synchronisieren
     args.each {|m| self.synchronize_method(m) }
    else
     # Wenn keine Methoden angegeben wurden, die als Nächstes
     # definierte Methode synchronisieren
     eigenclass = class<     # Eigenklasse zur Definition von Klassenmethoden verwenden
     eigenclass.class_eval do
     # method_added zur Benachrichtigung über nächste
     # Methodendefinition verwenden
     define_method :method_added do |name|
     # Zuerst diese Hook-Methode verwenden
     eigenclass.class_eval { remove_method :method_added }
     # Danach die soeben hinzugefügte Methode synchronisieren
     self.synchronize_method name
     end
     end
    end
# Fall 4: jeder andere Aufruf ist ein Fehler
else
    raise ArgumentError, "Falsche Argumente für synchronize()"
end
end
    Listing 8.9 Alias-Verkettung für Thread-Sicherheit
    8.11.3 Methodenverkettung für Tracing
    Listing 8.10 ist eine Variante von Listing 8.4 , die das Tracing benannter Methoden eines Objekts ermöglicht. In Listing 8.4 wurden Delegation und
method_missing
verwendet, um eine
Object.trace
-Methode zu definieren, die ein überwachendes Wrapper-Objekt zurückgibt. Diese Version verwendet Chaining, um Methoden eines Objekts an Ort und Stelle zu ändern. Sie definiert
trace!
und
untrace!
, um das Chaining benannter Methoden eines Objekts durchzuführen beziehungsweise aufzuheben.
    Das Interessanteste an diesem Beispiel ist, dass es das Chaining auf andere Weise durchführt als Listing 8.9 ; es definiert einfach Singleton-Methoden für das Objekt und verwendet innerhalb der Singletons
super
, um mit der ursprünglichen Methodendefinition zu verketten. Es werden keine Methoden-Aliase erzeugt.
    # Die Instanzmethoden trace! und untrace! für alle Objekte erzeugen.
# trace! "verkettet" die genannten Methoden durch die Definition von
# Singleton-Methoden, die Tracing-Funktionalität hinzufügen und
# dann super verwenden, um die Originalmethode aufzurufen.
# untrace! löscht die Singleton-Methoden, um das Tracing zu
# entfernen.
class Object
# Tracing der angegebenen Methoden, Ausgabe an STDERR senden
def trace!(*methods)
    @_traced = @_traced || [] # Die Tracing-Methoden merken
    # Wenn keine Methoden angegebenen wurden, alle Public-
    # Methoden verwenden, die direkt (nicht durch Vererbung)
    # von der Klasse des Objekts definiert werden
    methods = public_methods(false) if methods.size == 0
    methods.map! {|m| m.to_sym } # Strings in Symbole konvertieren
    methods -= @_traced # Tracing-Methoden entfernen
    # Sofort zurückkehren, wenn nichts zu tun ist
    return if methods.empty?
    # Methoden zu den Tracing-Methoden hinzufügen
    @_traced |= methods
    # Tracing der Tatsache, dass wir mit dem Tracing dieser
    # Methoden beginnen
    STDERR << "Tracing #{methods.join(', ')} von #{object_id}\n"
    # Singleton-Methoden werden in der Eigenclass definiert
    eigenclass = class << self; self; end
    methods.each do |m| # Für jede Methode m
     # Eine Singleton-Version der Methode m mit Tracing definieren.
     # Tracing-Informationen ausgeben und super verwenden, um die
     # Instanzmethode aufzurufen, die überwacht wird.
     # Wir wollen, dass die definierten Methoden in der Lage sind,
     # Blöcke entgegenzunehmen, so dass wir nicht define_method
     # verwenden können, sondern stattdessen einen String auswerten
     # müssen.
     # Beachten Sie, dass alles zwischen %Q{ und dem zugehörigen }
     # ein String in doppelten Anführungszeichen und kein Block ist.
     # Beachten Sie auch, dass es hier zwei Ebenen der String-Inter-
     # polation gibt. #{} wird interpoliert, wenn die

Weitere Kostenlose Bücher