2011-11-14 2 views
41

Sto provando a creare una classe, che ha un costruttore che accetta un singolo argomento. Quando creo una nuova istanza dell'oggetto, restituisce un puntatore.Oggetto ruby ​​viene stampato come puntatore

class Adder 
    def initialize(my_num) 
     @my_num = my_num 
    end 
end 
y = Adder.new(12) 
puts y 

Cosa sto sbagliando? Grazie

risposta

70

Quando si utilizza new metodo, si ottiene 'di riferimento' sul nuovo oggetto creato. Il metodo kernel puts restituisce alcune informazioni ruby ​​interne su questo oggetto. Se si desidera ottenere tutte le informazioni sullo stato l'oggetto, è possibile utilizzare il metodo getter:

class Adder 
    def initialize(my_num) 
    @my_num = my_num 
    end 
    def my_num 
    @my_num 
    end 
end 
y = Adder.new(12) 
puts y.my_num # => 12 

Oppure si può usare il metodo 'attr_reader' che definiscono un paio di setter e getter metodi dietro la scena:

class Adder 
    attr_accessor :my_num 

    def initialize(my_num) 
    @my_num = my_num 
    end  
end 
y = Adder.new(12) 
puts y.my_num # => 12 
+6

Sarebbe utile usare "attr_reader: my_num' qui invece di definire il proprio metodo che faccia lo stesso. – tadman

+1

Ovviamente, ma ho pensato che usare un metodo getter sarebbe stato più chiaro per topic starter :) Infatti, ho aggiornato il mio messaggio, grazie – WarHog

+5

Nota che attr_reader è stato menzionato e quindi è stato utilizzato attr_accessor. attr_reader funziona anche. Permette solo di ottenere il valore, mentre attr_accessor ti permette anche di assegnare un nuovo valore a my_num. –

4

Questo perché l'oggetto è un puntatore. In Ruby, tutti gli oggetti sono allocati nell'heap e le variabili sono solo riferimenti a essi.

Quando si esegue

puts y 

In realtà è chiamando il metodo to_s di default dell'oggetto, che è solo per emettere il nome della classe, la posizione di memoria, e alcune informazioni sulle variabili dell'oggetto istanza.

4

Il rubino non ha puntatori. Nell'esempio, è un'istanza di Adder con una variabile di istanza denominata @my_num con il valore di 12 (che è esso stesso un oggetto Fixnum).

Il metodo puts chiama il metodo to_s di qualunque argomento lo si passi. Questo è ciò che vedi output; forse pensi che l'output si riferisca a un puntatore, ma è solo una rappresentazione testuale dell'oggetto. Puoi cambiarlo sostituendo il metodo di istanza to_s per qualsiasi classe.

15

Non stai facendo niente di male. Supponendo che tu veda qualcosa come #<Adder:0xb7f9f710 @my_num=12> quindi in Ruby questa è solo la rappresentazione predefinita dell'oggetto che hai creato.

Se si desidera modificare questo comportamento per renderlo più amichevole quando si passa l'oggetto a puts, è possibile sovrascrivere il metodo to_s (in stringa). per esempio.

class Adder 
    def initialize(my_num) 
    @my_num = my_num 
    end 

    def to_s 
    "Adder with my_num = #{@my_num}" 
    end 
end 

poi quando lo fai puts y vedrete Adder with my_num = 12

È anche possibile eseguire l'override del metodo inspect che è quello che viene utilizzato, ad esempio, quando la console IRB Rubino Stampa la rappresentazione del vostro oggetto per esempio

class Adder 
    def inspect 
    to_s # return same representation as to_s 
    end 
end 

poi nel IRB:

>> y = Adder.new 12 
=> Adder with my_num = 12