2016-06-01 6 views
0

私はPOODRの本を読んでおり、デフォルト値で初期化するために古い構文を使用しています。私は新しい構文と同じを実装する必要があります。キーワードargsを使用したrubyの初期化

class Gear 
    attr_reader :chainring, :cog, :wheel 
    def initialize(args) 
    @chainring = args.fetch(:chainring, 40) 
    @cog = args.fetch(:cog, 10) 
    @wheel = args[:wheel] 
    end 

    def gear_inches 
    ratio * diameter 
    end 

    def diameter 
    wheel * diameter 
    end 
end 

Gear.new(chainring: 52, cog: 11, wheel: Wheel.new(26,1.5)).gear_inches 

新しいキーワードargsではどのように見えますか?これは下の私の推測ですが、上のようなホイールでも同じ結果になるかどうかはわかりません。 :wheelが必要となりますので、古いコードにはそれがなかったのに対し、キーワード引数を指定して

class Gear 
    attr_reader :chainring, :cog, :wheel 
    def initialize(chainring: 40, cog: 10, wheel:) #is this good here for wheel? 
    @chainring = chainring 
    @cog = cog 
    @wheel = wheel #is this good here for wheel? 
    end 

    ...... 
end 
+0

'wheel:nil'は同等です – Stefan

答えて

0

あなたの例では、古い方法と同等ではありません。

キーワードをオプションにする場合は、キーワードargsを使用できません。

+0

私はStefanが上記のコメントで示唆したことをしましたか? –

1

リテラル同等はこのようになります:

class Gear 
    def initialize(**args) 
    @chainring = args.fetch(:chainring, 40) 
    @cog = args.fetch(:cog, 10) 
    @wheel = args[:wheel] 
    end 
end 

元のコードは、任意のキーを渡すことができますし、それは必要としないものを無視し、それゆえ、私たちができるようにする** ksplatを使用任意の引数。

私たちは、これにそのコードをリファクタリングできます

class Gear 
    def initialize(chainring: 40, cog: 10, **args) 
    @chainring = chainring 
    @cog = cog 
    @wheel = args[:wheel] 
    end 
end 

これはわずかに良い読み込みます。しかし、それはまだ悪いデザインです:なぜユーザーは任意のキーを渡すことができますか?使用されていないキーが渡されると、バグが発生する可能性が最も高くなります。例えば。ユーザーはGear.new(cgo: 20)と明記していますが、間違ったデータ(cogの値は10)が表示されます。

class Gear 
    def initialize(chainring: 40, cog: 10, wheel: nil) 
    @chainring = chainring 
    @cog = cog 
    @wheel = wheel 
    end 
end 

これは、元のコードの行動を意図と同等ですが、私は推測します。それは、任意のキーを渡すことを許可していない点で、動作が異なりますが、とにかくそれが意味をなさないと思います。したがって、等価ではありませんが、間違いなくより良いです。

しかし、まだ問題があります(元のコードにもあります)。wheelを渡すことができず、wheelが終了します。nilになります。しかし、wheelは無条件で使用されます(たとえばdiameter)。これは、実行時にwheelnilのときに吹き飛ばされることを意味します。だから、wheelが渡されることを必要とする方が良いです:あなたが持っていた、もちろん、ある

class Gear 
    def initialize(chainring: 40, cog: 10, wheel:) 
    @chainring = chainring 
    @cog = cog 
    @wheel = wheel 
    end 
end 

、まさに。これはではなく、相当の動作ですが、私はそれを気にしますはの意味でと同等で、おそらくはるかに正確で正確です。

+0

Jorg、詳細な回答ありがとう!私は2つの質問があります:1.最後の例で@chainring = chainring'の代わりに '@chainring = args [:chainring]'を使用するように教えてください(質問は@cogと@wheelにもなります) ? 2.もしホイールをオプションにしたいのであれば、argsに 'wheel:nil'を使うことができますが、それを必要としたいのであれば、引数に' wheel: 'を使うだけです。 –

関連する問題