Cast value type during attr_accessor

I am new to Ruby and learn it using "Programming Ruby 1.9" (PickAxe). In the book, I see a program that I modified in this way:

1 #!/usr/bin/env ruby -w 2 3 class BookInStock 4 attr_reader :isbn 5 attr_accessor :price 6 def initialize(isbn, price) 7 @isbn = isbn 8 @price = Float(price) 9 end 10 # def price=(price) 11 # @price = Float(price) 12 # end 13 end 14 15 b1 = BookInStock.new("isbn1", 3) 16 p b1 17 b2 = BookInStock.new("isbn2", 3.14) 18 p b2 19 b3 = BookInStock.new("isbn3", "5.67") 20 p b3 21 b3.price = "10.32" 22 p b3 

Line number 8 ensures that the correct value is assigned to b3.price .

But how can I handle cases like line number 21 without using a method like line 10-12?

Is there a way I can change attr_accessor for this? Or I ask too much: D

I could not find such links on the Internet.

+1
source share
3 answers

attr_accessor :sym is a class method that defines simple getter and setter methods.

You can define your own casting_attr_accessor :

 class Class def casting_attr_accessor(accessor, type) define_method(accessor) do instance_variable_get("@#{accessor}") end define_method("#{accessor}=") do |val| instance_variable_set("@#{accessor}", Kernel.send(type.to_s, val)) end end end 

And then in your class use it like

 casting_attr_accessor :price, Float 
+2
source

You cannot do this without calling your own setter method. What the attr_accessor :method does internally just generates the easiest installation method for you:

 def method=(val) @method = val end 

You need to write a more advanced configuration method (in your case, the installer will contain the conversion of the string to floating) manually.

+1
source

Yes, you ask too much. You will need to define price= in the same way as in your commented code.

attr_accessor is just a simplified way to define

 def price=(val) @price = val end 

(no type conversion) plus getter method.

Obviously, when you define price= , attr_accessor :price no longer needed (only attr_reader ).

Finally, I would prefer to write val.to_f instead of Float(val) .

+1
source

Source: https://habr.com/ru/post/1345596/


All Articles