Ottieni l'elenco dei metodi di istanza di una classe


98

Ho una lezione:

class TestClass
  def method1
  end

  def method2
  end

  def method3
  end
end

Come posso ottenere una lista dei miei metodi di questa classe ( method1, method2, method3)?

Risposte:


115

Lo vuoi davvero TestClass.instance_methods, a meno che tu non sia interessato a ciò che TestClasspuò fare di per sé.

class TestClass
  def method1
  end

  def method2
  end

  def method3
  end
end

TestClass.methods.grep(/method1/) # => []
TestClass.instance_methods.grep(/method1/) # => ["method1"]
TestClass.methods.grep(/new/) # => ["new"]

Oppure puoi chiamare methods(non instance_methods) sull'oggetto:

test_object = TestClass.new
test_object.methods.grep(/method1/) # => ["method1"]

3
Eh, mi hai battuto per 47 secondi. +1
Phrogz

2
Quando provo print TestClass.new.instance_methods, ottengo questo erroremy_class.rb:10:in <main>: undefined method instance_methods for #<TestClass:0x96b9d20> (NoMethodError)
Vladimir Tsukanov

Hai solo bisogno di fare TestClass.new.methods. Forse "esso" era ambiguo nella mia risposta.
Andrew Grimm

Nota che sotto Ruby 1.9+ gli array dei nomi dei metodi sono simboli, non stringhe.
Phrogz

1
@Phrogz: Sì, ma puoi usare espressioni regolari su di loro. Non evochi nemmeno Cthulhu! :) Anche se [:method1]invece avresti .
Andrew Grimm

113
TestClass.methods(false) 

per ottenere solo metodi che appartengono solo a quella classe.

TestClass.instance_methods(false) restituirebbe i metodi dal tuo esempio dato (poiché sono metodi di istanza di TestClass).


2
Questo è un ottimo modo per verificare se una classe ha metodi polimorfizzati da una classe base pseudo-interfaccia / astratta senza dover provare a chiamare direttamente i metodi.
Daniel Doezema

2
La risposta accettata è ottima, ma questa è probabilmente quello per cui verranno qui più persone!
Aaron

Questa dovrebbe essere sicuramente la risposta accettata. GRAZIE!
Vinicius Brasil

38
TestClass.instance_methods

o senza tutti i metodi ereditati

TestClass.instance_methods - Object.methods

(Era "TestClass.methods - Object.methods")


25
o senza metodi ereditati: TestClass.methods(false).
sawa

2
@sawa TestClass.methods(false)ritorna vuoto
Vladimir Tsukanov

1
Questa risposta è sbagliata; i risultati non includeranno method1, method2o method3, poiché questi sono metodi di istanze della classe, non metodi TestClassdell'oggetto stesso.
Phrogz

1
@Phrogz: Oops ... sì, "TestClass.instance_methods - Object.methods" o "TestClass.new.methods - Object.methods" ... che mi insegnerà a non avviare una console. È meglio per me eliminare questa risposta o modificarla?
Pavimentazione

1
@ Pavling Modifica sicuramente la tua risposta per essere corretta. (Presto, prima che l'OP assegni il merito a qualcun altro! :)
Phrogz

6

È possibile ottenere un elenco più dettagliato (ad esempio strutturato definendo la classe) con gemme come il debug o il looksee .


6
$ irb --simple-prompt

class TestClass
  def method1
  end

  def method2
  end

  def method3
  end
end

tc_list = TestClass.instance_methods(false)
#[:method1, :method2, :method3]
puts tc_list
#method1
#method2
#method3

2
Questo è troppo simile ad altre risposte e non aggiunge ulteriori informazioni o chiarezza.
Sostanziale

3
Hai esitato a dire che è anche molto tardi. : D
Douglas G. Allen

2

Secondo Ruby Doc instance_methods

Restituisce un array contenente i nomi dei metodi di istanza pubblici e protetti nel ricevitore. Per un modulo, questi sono i metodi pubblici e protetti; per una classe, sono i metodi di istanza (non singleton). Se il parametro facoltativo è false, i metodi di eventuali antenati non vengono inclusi. Sto prendendo l'esempio della documentazione ufficiale.

module A
  def method1()  
    puts "method1 say hi"
  end
end
class B
  include A #mixin
  def method2()  
     puts "method2 say hi"
  end
end
class C < B #inheritance
  def method3() 
     puts "method3 say hi"
  end
end

Vediamo l'output.

A.instance_methods(false)
  => [:method1]

A.instance_methods
  => [:method1]
B.instance_methods
 => [:method2, :method1, :nil?, :===, ...# ] # methods inherited from parent class, most important :method1 is also visible because we mix module A in class B

B.instance_methods(false)
  => [:method2]
C.instance_methods
  => [:method3, :method2, :method1, :nil?, :===, ...#] # same as above
C.instance_methods(false)
 => [:method3]

0

Per ottenere solo metodi propri ed escludere quelli ereditati:

Dall'interno dell'istanza:

self.methods - self.class.superclass.instance_methods

Da fuori:

TestClass.instance_methods - TestClass.superclass.instance_methods

Aggiungilo alla classe:

class TestClass
  class << self
    def own_methods
      self.instance_methods - self.superclass.instance_methods
    end
  end
end

TestClass.own_methods
=> [:method1, :method2, method3]

(con rubino 2.6.x)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.