0

I've created the following class

class BankAccount                                                       
  def accountNumber                                                   
    @accountNumber=5                                                
  end                                                                 
  def accountNumber=(value)                                           
    @accountNumber=value                                            
  end                                                                 
end    

and I use it like this:

account=BankAccount.new
=> #<BankAccount:0x0000000295d6c8>
account.accountNumber
=> 5
account.accountNumber="223"
=> 223
account.accountNumber
=> 5

why is accountNumber equal to 5 even after setting it to 223?

builder-7000
  • 7,131
  • 3
  • 19
  • 43
  • Note: Ruby is a case-sensitive language and capital letters have specific meaning in terms of syntax. Variables and method names should be lower-case letters. Capitals indicate constants of the form `ClassName` or `CONSTANT_NAME`. – tadman Apr 02 '19 at 23:51

2 Answers2

4

When you call account.accountNumber, it calls the accountNumber method, which you defined as:

def accountNumber                                                   
  @accountNumber=5                                                
end                                                                 

There are a couple ways to fix this, a simple one is:

class BankAccount
  attr_accessor :account_number

  def initialize(account_number=5)
    @account_number = account_number
  end
end

Which works great:

irb(main):009:0> x = BankAccount.new
=> #<BankAccount:0x00007fae449c5fc8 @account_number=5>
irb(main):010:0> x.account_number = 10
=> 10
irb(main):011:0> y = BankAccount.new
=> #<BankAccount:0x00007fae4495fed0 @account_number=5>
irb(main):012:0> y.account_number
=> 5
irb(main):013:0> z = BankAccount.new
=> #<BankAccount:0x00007fae480066a0 @account_number=5>
irb(main):015:0> z.account_number = 15
=> 15
irb(main):016:0> z.account_number
=> 15

Here's a SO answer diving into how attr_accessor works.

tsm
  • 3,598
  • 2
  • 21
  • 35
  • I see, so my original class was setting `@accountNumber` to 5 every time i called the `accountNumber` method. Thanks for the insight. – builder-7000 Apr 02 '19 at 20:33
  • 1
    The answer you link in your last sentence was written in 2010 and to date has 2,177 upvotes. It's a perfectly fine answer, but I shake my head when I see mundane, stone-age questions whose answers have received thousands of upvotes. Ah, to have lived in the days of the low-hanging fruit! – Cary Swoveland Apr 02 '19 at 21:33
2

When you call account.accountNumber you every time assign @accountNumber as 5 because of your method.

To avoid this you can do it like this:

class BankAccount
  DEFAULT_NUMBER = 5
  DEFAULT_AMOUNT = 10

  attr_accessor :number, :amount

  def initialize
    set_default_values
  end

  def set_default_values
    @number = DEFAULT_NUMBER
    @amount = DEFAULT_AMOUNT
  end
end

And now you can assign values as you like

account = BankAccount.new # => #<BankAccount:0x000055d581adbd38 @number=5 @amount=10>

account.number = 500
account.number # => 500

account.amount = 20
account.amount # => 20

account.amount = BankAccount::DEFAULT_AMOUNT
account.amount # => 10

account.set_default_values
account # => #<BankAccount:0x000055d581adbd38 @number=5 @amount=10>
mechnicov
  • 12,025
  • 4
  • 33
  • 56
  • I assume you would only do this if you might want to call `set_default_value` sometime after creating the instance (if you wanted to reset its value to `5`). Right? (Else you could just write `@number = 5` in `initialize`). – Cary Swoveland Apr 02 '19 at 21:42
  • @CarySwoveland, I've updated my answer with "constant idea" – mechnicov Apr 02 '19 at 22:08