2014-10-14 7 views
5

Stavo lavorando su un semplice Pi Generator mentre apprendevo Ruby, ma continuavo a ottenere NoMethodError su RubyMine 6.3.3, così ho deciso di creare un nuovo progetto e una nuova classe il più semplice possibile, e I STILL ottenere NoMethodError. Qualche ragione?Ruby: NoMethodError, ma perché?

class Methods 
    def hello (player) 
    print "Hello, " << player 
    end 
    hello ("Annie") 
end 

E l'errore che ottengo è:

C:/Users/Annie the Eagle/Documents/Coding/Ruby/Learning Environment/methods.rb:5:in `<class:Methods>': undefined method `hello' for Methods:Class (NoMethodError) 
+0

si sta chiamando il metodo all'interno della definizione di classe. Non sono sicuro che sia previsto. – Tensibai

+0

Non sono sicuro del tuo background/livello di esperienza nella programmazione OO, quindi per verificare: capisci la differenza tra classi e istanze (e metodi di classe e metodi di istanza)? La risposta presuppone che tu ... –

risposta

7

È stato definito un metodo di esempio e stanno cercando di chiamarlo come un metodo di una classe. Pertanto è necessario rendere il metodo hello un metodo di classe, non un metodo di istanza della classe Methods.

class Methods 
    def self.hello(player) 
    print "Hello, " << player 
    end 
    hello("Annie") 
end 

Oppure, se si vuole definirlo come metodo di istanza quindi chiamare come qui sotto:

class Methods 
    def hello(player) 
    print "Hello, " << player 
    end 
end 
Methods.new.hello("Annie") 
+0

Oh wow ... così self.hello sarebbe uguale all'equivalente C# di "statico (tipo di ritorno) ciao"? Quando sarebbe giusto usare solo "def ciao" –

+0

È necessario rimuovere lo spazio tra il nome del metodo e la parentesi. – Stefan

+0

@Stefan Grazie mille! –

0

Definendo un metodo con def METHOD_NAME args si sta definendo un metodo di istanza che sarà incluso in ogni oggetto di quella classe, ma non nella classe stessa.

D'altra parte, per def self.method_name args si otterrà un metodo di classe che sarà direttamente nella classe, senza la necessità di instanciate un oggetto da esso.

Quindi, se avete questo:

Class Test 
    def self.bar 
    end 

    def foo 
    end 

end 

È possibile eseguire il metodo di istanza in questo modo:

a = Test.new 
a.foo 

E per quanto riguarda la classe di uno dovrebbe essere:

Test.foo 
1

È stai provando a chiamare un metodo di istanza come metodo di classe.

Ecco po 'di codice che illustra la differenza tra i due in Ruby:

class Person 

    # This is a class method - note it's prefixed by self 
    # (which in this context refers to the Person class) 
    def self.species 
    puts 'Human' 
    # Note: species is OK as a class method because it's the same 
    # for all instances of the person class - ie, 'Bob', 'Mary', 
    # 'Peggy-Sue', and whoever else, are ALL Human. 
    end 

    # The methods below aren't prefixed with self., and are 
    # therefore instance methods 

    # This is the construct, called automatically when 
    # a new object is created 
    def initialize(name) 
    # @name is an instance variable 
    @name = name 
    end 

    def say_hello 
    puts "Hello from #{@name}" 
    end 

end 

E ora provarlo, chiamando i metodi ...

# Call a class method... 
# We're not referring to any one 'instance' of Person, 
Person.species #=> 'Human' 

# Create an instance 
bob = Person.new('Bob') 

# Call a method on the 'Bob' instance 
bob.say_hello #=> 'Hello from Bob' 

# Call a method on the Person class, going through the bob instance 
bob.class.species #=> 'Human' 

# Try to call the class method directly on the instance 
bob.species #=> NoMethodError 

# Try to call the instance method on the class 
# (this is the error you are getting) 
Person.say_hello #=> NoMethodError 
1

Hai creato un metodo di istanza , ma stai chiamando un metodo di classe. Per chiamare hello("Annie"), devi creare un'istanza di metodi. Per esempio:

class Methods 
    def self.hello(player) 
     print "Hello, " << player 
    end 
end 

my_method = Methods.new 
my_method.hello("Annie) 

Questo sarebbe uscita Hello from Annie