2012-11-15 5 views
2

J'ai cette classe:mathématiques avec les variables d'instance

class Account 
    attr_accessor :balance 
    def initialize(balance) 
      @balance = balance 
    end 
    def credit(amount) 
      @balance += amount 
    end 
    def debit(amount) 
      @balance -= amount 
    end 
end 

Ensuite, par exemple, plus tard dans le programme:

bank_account = Account.new(200) 
bank_account.debit(100) 

Si j'appelle la méthode de débit avec l'opérateur - dans "=" (comme indiqué dans la classe ci-dessus), le programme échoue avec le message suivant:

bank2.rb:14:in `debit': undefined method `-' for "200":String (NoMethodError) 
from bank2.rb:52:in `<main>' 

Mais si je retire le signe moins et juste faire @bal ance = montant, alors ça marche. Évidemment, je veux qu'il soustrait, mais je ne peux pas comprendre pourquoi cela ne fonctionne pas. Est-ce que maths ne peut pas être fait avec des variables d'instance?

Répondre

3

Votre valeur passée dans initialize() est une chaîne plutôt qu'un nombre entier. Cast à un int via .to_i.

def initialize(balance) 
    # Cast the parameter to an integer, no matter what it receives 
    # and the other operators will be available to it later  
    @balance = balance.to_i 
end 

De même, si le paramètre passé à debit() et credit() est une chaîne, le jeter à un int.

def credit(amount) 
    @balance += amount.to_i 
end 
def debit(amount) 
    @balance -= amount.to_i 
end 

Enfin, je vais ajouter que si vous prévoyez de mettre @balance en dehors de la méthode initialize(), il est recommandé de définir son setter d'appeler .to_i implicitement.

def balance=(balance) 
    @balance = balance.to_i 
end 

Remarque: Cela suppose que vous souhaitez uniquement utiliser des valeurs entières. Utilisez .to_f si vous avez besoin de valeurs à virgule flottante.

+0

Conversations forcées L'ion est toujours une bonne idée car il vous permet d'utiliser des choses qui ne sont pas des nombres, mais * pourrait * être des nombres si vous le demandez gentiment. – tadman

+0

Michael - votre commentaire que je passais une chaîne dans initialize() m'a fait réaliser où est mon problème. J'utilisais un exemple dans ma question, mais la façon dont je suis en train de faire une nouvelle classe provient d'un argument (ARGV). Quand je lance le programme, je tape quelque chose comme "ruby bank2.rb 1000" qui fera ensuite un nouveau compte avec 1000 comme solde. Donc, je suppose maintenant que peut-être les arguments sont toujours lus en tant que chaînes de caractères et c'est de là que vient tout mon problème de chaîne. J'utilisais .to_i partout ailleurs sauf dans initialize(). Je vais essayer après le travail aujourd'hui. – cliff900

+0

@ cliff900 Oui, ARGV contient toujours des chaînes. –

0

essayer avec

def credit(amount) 
     @balance += amount.to_i 
end 
def debit(amount) 
     @balance -= amount.to_i 
end 

ou passez un numéro comme paramètre (l'erreur indique que vous passez une chaîne)

+0

Merci. Je passais en fait la valeur à la méthode de débit comme ceci: 'code'bank_account.debit (amount.to_i)' code 'qui je pense fonctionnera. Je pense que j'ai trouvé ma question dans le commentaire que j'ai laissé dans la dernière réponse, cependant. – cliff900

3

Très probablement, vous avez

bank_account = Account.new("200") 

Vous devriez effectivement faire

bank_account = Account.new(200) 
Questions connexes