2016-10-06 7 views
1

ich die Stripe-API zu lesen, und ich sehe dies:Stripe API öffnet die Metaklasse? Oder einfach eine Klassenmethode definieren?

module Stripe 

    ... 

    class << self 
    attr_accessor :stripe_account, :api_key, :api_base, :verify_ssl_certs, :api_version, :connect_base, :uploads_base, 
        :open_timeout, :read_timeout 

    attr_reader :max_network_retry_delay, :initial_network_retry_delay 
    end 

Was ist da los? Ich habe versucht, Yehuda Katz Blog zu lesen, aber Teile davon sind irgendwie unklar, wie folgt:

Was ist los in den zwei Beispielen, die er bietet?

Es stellt sich heraus, dass all diesen Zusammenbruch seltsamen Regeln nach unten in ein einziges Konzept: die Kontrolle über das Selbst in einem bestimmten Teil des Codes. Gehen wir zurück und werfen Sie einen Blick auf einige der Schnipsel wir früher aussah:

class Person  
    def name 
     "Matz" 
    end 

    self.name #=> "Person" 
end 

Hier haben wir den Namen Methode die Person-Klasse hinzufügen. Sobald wir class Person sagen, das Selbst bis zum Ende ist der Block die Person Klasse selbst.

Person.class_eval do  
    def name 
     "Matz" 
    end 

    self.name #=> "Person" 
end 

Hier machen wir genau die gleiche Sache: den Namen Methode, um Instanzen der Person Klasse hinzufügen. In dieser Fall, setzt class_eval das Selbst zu Person bis Ende der Block. Das ist alles perfekt geradlinig, wenn sie mit Klassen zu tun, aber es ist ebenso geradlinig, wenn sie mit metaclasses Umgang:

Warum Yehuda halten Schreiben:

self.name #=> "Person"

Antwort

2

Es gibt nicht so etwas wie "Klassenmethode" in Ruby. Alle Methoden sind Instanz Methoden. Die Sache ist nur, dass die Instanzen anders sind.

Stripe ist eine Instanz der Klasse Module und Person ist eine Instanz der Klasse Class.

Also in Ihrem ersten Beispiel (Stripe) gibt es eine Definition von attr_accessor s verfügbar für Objekt Stripe.

So können Sie Stripe Attribute lesen und schreiben:

Stripe.api_key = :some_key 
Stripe.api_key 
#=> :some_key 

Während die folgenden ein Verfahren zur Verfügung, um Instanzen der Klasse definiert Person

Person.class_eval do 
    def name 
    "Matz" 
    end 
end 

Sie verfügbar definierte Instanzmethode haben könnte zu Person Klasse mit instance_eval, die den Code im Zusammenhang mit dem Empfänger ausgewertet:

Person.instance_eval do 
    def name 
    "Matz" 
    end 
end 
Person.name # this is what they sometimes called "a class method", which I don't like personally 
#=> 'Matz' 

Es ist immer nur eine Frage des Zusammenhangs. Sobald Sie verstehen, was self ist und wo self Punkte in jedem Moment zeigt - Dinge werden so viel klarer.

+0

Warum Yehuda rechts: 'self.name # =>" Person "' – Jwan622

+1

@ Jwan622, weil es ein Kontext von 'Person' ist. Wie gesagt, es ist immer eine Frage des Selbst. Innerhalb des Klassenkörpers befinden Sie sich im Kontext dieser Klasse, was bedeutet, dass "selbst" auf die Klasse selbst verweist. Es ist das gleiche, als ob Sie 'Person.name' außerhalb der Klassendefinition schreiben würden. –

+0

oh' name' ist eine eingebaute Funktion. – Jwan622

Verwandte Themen