2

I have a class Player which has a variable @hitpoints in the initialize method. I have made the variable accessible by use of attr_accessor :hitpoints.

The variable is indeed accessible when an instance of the class Player is created. However, I would like to allow only writing of an integer to it. As of now, I can assign a string:

conan.hitpoints = "Hello there!"

Any idea how to accomplish this?

2 Answers 2

1

Another common practice is to convert the argument, e.g. using to_i:

def hitpoints=(value)
  @hitpoints = value.to_i
end

10.to_i    #=> 10
10.5.to_i  #=> 10
"10".to_i  #=> 10
"foo".to_i #=> 0

or Integer:

def hitpoints=(value)
  @hitpoints = Integer(value)
end

Integer(10)    #=> 10
Integer(10.5)  #=> 10
Integer("10")  #=> 10
Integer("foo") #=> ArgumentError: invalid value for Integer(): "foo"

Note that you don't necessarily have to type check your arguments. Ruby will raise an exception sooner or later if the object doesn't behave as expected:

health = 100
hitpoints = "foo"

health -= hitpoints #=> TypeError: String can't be coerced into Fixnum
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much all. Special thanks to Stefan:) That worked out nicely for me. I used the suggestion of @hitpoints = Integer(value).
1

You can write a custom setter for it:

class Player
  attr_accessor :hitpoints

  def hitpoints=(value)
    raise 'Not an integer' unless value.is_a? Integer
    @hitpoints = value
  end
end

You should also use this setter in your initialization method instead of instance variable:

def initialize(hitpoints)
  self.hitpoints = hitpoints
end

UPDATE:

About attr_accessor. This method defined both setter and getter method for an attribute. Because you are defining your own setter later in the code, the default one is not needed and may be discarded with attr_reader, as suggested in comments by Stefan and Arup.

I have pretty mixed feelings about this though, as if you were working with somebody else, he will firstly noticed attr_reader at the top of your class and will think - Hey, why is it a read_only attribute? If it is a new developer, it might even cause him to write some nonsense code.

I believe that the code is to show its purpose, hence I would use attr_accessor even if it gives me method redefined warning. This is however a matter of personal preference.

7 Comments

Yes that's the way I also thinking.. But why attr_accessor :hitpoints is still needed ?
use attr_reader :hitpoints to avoid a method redefined warning
@BroiSatse Go as Stefan said.
@Stefan - I've updated the answer to put my views on attr_accessor vs attr_reader
@BroiSatse on the other hand, a new developer could stop reading once he see the attr_accessor declaration, assuming the class is using the default setter.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.