404 Stimmen

Rubin: Aufruf einer Klassenmethode aus einer Instanz

Wie ruft man in Ruby eine Klassenmethode von einer Instanz dieser Klasse aus auf? Nehmen wir an, ich habe

class Truck
  def self.default_make
    # Class method.
    "mac"
  end

  def initialize
    # Instance method.
    Truck.default_make  # gets the default via the class's method.
    # But: I wish to avoid mentioning Truck. Seems I'm repeating myself.
  end
end

die Linie Truck.default_make ruft den Standardwert ab. Aber gibt es eine Möglichkeit, dies zu sagen, ohne zu erwähnen Truck ? Es sieht so aus, als sollte es das geben.

646voto

Mark Rushakoff Punkte 236626

Anstatt sich auf den wörtlichen Namen der Klasse zu beziehen, können Sie innerhalb einer Instanzmethode einfach self.class.whatever .

class Foo
    def self.some_class_method
        puts self
    end

    def some_instance_method
        self.class.some_class_method
    end
end

print "Class method: "
Foo.some_class_method

print "Instance method: "
Foo.new.some_instance_method

Ausgänge:

Class method: Foo
Instance method: Foo

216voto

Mark B Punkte 2097

Verwendung von self.class.blah ist NICHT dasselbe wie die Verwendung von ClassName.blah wenn es um das Erbe geht.

class Truck
  def self.default_make
    "mac"
  end

  def make1
    self.class.default_make
  end

  def make2
    Truck.default_make
  end
end

class BigTruck < Truck
  def self.default_make
    "bigmac"
  end
end

ruby-1.9.3-p0 :021 > b=BigTruck.new
 => #<BigTruck:0x0000000307f348> 
ruby-1.9.3-p0 :022 > b.make1
 => "bigmac" 
ruby-1.9.3-p0 :023 > b.make2
 => "mac"

25voto

Harish Shetty Punkte 63187

Um auf eine Klassenmethode innerhalb einer Instanzmethode zuzugreifen, gehen Sie wie folgt vor:

self.class.default_make

Hier ist eine alternative Lösung für Ihr Problem:

class Truck

  attr_accessor :make, :year

  def self.default_make
    "Toyota"
  end

  def make
    @make || self.class.default_make
  end

  def initialize(make=nil, year=nil)
    self.year, self.make = year, make
  end
end

Lassen Sie uns nun unsere Klasse verwenden:

t = Truck.new("Honda", 2000)
t.make
# => "Honda"
t.year
# => "2000"

t = Truck.new
t.make
# => "Toyota"
t.year
# => nil

7voto

yfeldblum Punkte 64211
self.class.default_make

4voto

Jason Machacek Punkte 974

Sie machen das schon richtig. Klassenmethoden (ähnlich den "statischen" Methoden in C++ oder Java) sind nicht Teil der Instanz, so dass sie direkt referenziert werden müssen.

In diesem Sinne wäre es in Ihrem Beispiel besser, wenn Sie "default_make" zu einer regulären Methode machen würden:

#!/usr/bin/ruby

class Truck
    def default_make
        # Class method.
        "mac"
    end

    def initialize
        # Instance method.
        puts default_make  # gets the default via the class's method.
    end
end

myTruck = Truck.new()

Klassenmethoden sind nützlicher für Funktionen vom Typ Utility, die die Klasse verwenden. Zum Beispiel:

#!/usr/bin/ruby

class Truck
    attr_accessor :make

    def default_make
        # Class method.
        "mac"
    end

    def self.buildTrucks(make, count)
        truckArray = []

        (1..count).each do
            truckArray << Truck.new(make)
        end

        return truckArray
    end

    def initialize(make = nil)
        if( make == nil )
            @make = default_make()
        else
            @make = make
        end
    end
end

myTrucks = Truck.buildTrucks("Yotota", 4)

myTrucks.each do |truck|
    puts truck.make
end

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X