2012-01-20 11 views
1

私はRuby初心者で、「プログラミングRuby 1.9」(PickAxe)を使って学習しています。attr_accessorのキャスト値を入力してください

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 

行番号8は、正しい値がb3.priceに割り当てられていることを保証します。本の中で、私はこのように修正プログラムを参照してください。

しかし、10行目のような方法を使用せずに21行目のようなケースを処理するにはどうすればよいですか?

attr_accessorを変更する方法はありますか?または、私はあまりにも多くを求めています:D

私はそのような参考文献をオンラインで見つけることができませんでした。

+0

のようにそれを使用しています。 '0.30 + 0.30 + 0.30'は' 0.8999999999999999'となる。 –

+0

財務計算が必要な場合は、Floatの代わりに[BigDecimal](http://www.ruby-doc.org/stdlib-1.9.3/libdoc/bigdecimal/rdoc/BigDecimal.html)を使用してください –

+0

ありがとうございます。他の参考文献でそのことを読んでください。ちょうどこれが始めるのは簡単な例でした。提案にもう一度感謝します。 –

答えて

2

attr_accessor :symは、単純なゲッターとセッターメソッドを定義するクラスのメソッドです。

独自01​​を定義することができます。

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 

そして、あなたのクラスであなたがFloat`s `での価格を保存することはありません

casting_attr_accessor :price, Float 
1

独自のセッターメソッドを記述することなくこれを行うことはできません。内部的にちょうどあなたの最も簡単なsetterメソッドが生成されない何attr_accessor :method

あなたは、より高度なsetterメソッドを記述する必要が
def method=(val) 
    @method = val 
end 

手動で(あなたのケースセッターに文字列から浮動小数点の変換が含まれます)。

1

はい、あなたはあまりにも多くを求めています。コメントアウトされたコードと同じように、price=を正確に定義する必要があります。

attr_accessorプラスゲッターメソッド(型変換なしで)

def price=(val) 
    @price = val 
end 

を定義するだけで簡単な方法です。

明らかにprice=を定義すると、attr_accessor :priceはもう必要ありません(attr_readerのみ)。

最後に、Float(val)の代わりにval.to_fと書きます。

+0

'attr_accessor'は文法的な砂糖ではありませんが、退屈な普通の古いメッセージです。 –

+0

@JörgWMittag:そうです。ありがとうございました。 –

関連する問題