この広告は、90日以上更新していないブログに表示しています。
これ知らなかった。こんな感じで配列を引数にとる場合、「配列」、「nil」、「引数1個」を一括で処理したいと思うことがあると思う。こんな時にこれを解決する方法があった。
これは使っていこう。
以下のコードをベースに説明。
classPizzadefinitialize(toppings) toppings.eachdo |topping| add_and_price_topping(topping)endendend
本書でも紹介されているが、引数を可変長引数に変えるというアプローチで対応していたのだけど、これだと、*
を使う必要がある。また、受け付けた引数を配列に変換し、何を操作しているのかはっきりわかる方がいいとのこと。
classPizza# 可変長引数を展開definitialize(*toppings) toppings.eachdo |topping| add_and_price_topping(topping)endendend# こうすると、以下に対応できる。Pizza.new("cheeze","bacon")Pizza.new("cheeze")Pizza.new(nil)
Kernel#Array
知らんかったわ。to_ary
を先に試して、to_a
をそのあと試すとのこと。
> ?Kernel#ArrayFrom: object.c (CMethod):Owner:KernelVisibility:privateSignature: Array(arg1)Number oflines:14Returns arg as anArray.First tries to call to_ary on arg, then to_a.If arg doesnot respond to to_aryor to_a,returns anArray of length1 containing arg.If to_aryor to_a returns something other thananArray, raises aTypeError. Array(["a","b"])#=> ["a", "b"] Array(1..5)#=> [1, 2, 3, 4, 5] Array(key::value)#=> [[:key, :value]] Array(nil)#=> [] Array(1)#=> [1]
例。
>> Array("Betelgeuse")=> ["Betelgeuse"]>> Array(nil)=> []>> Array(["Nadroj","Retep"])=> ["Nadroj","Retep"]# Hashは問題となる可能性がある>> Array(a:20)=> [[:a,20]]
最初のコードを変更すると
classPizzadefinitialize(toppings)# これだけ Array(toppings).eachdo |topping| add_and_price_topping(topping)endendend# 以下に対応できるPizza.new(["cheeze","bacon"])Pizza.new("cheeze")Pizza.new(nil)# 以下はNG# だが、引数の意味が分かりやすくなるPizza.new("cheeze","bacon")
さらっと流されていたが、to_ary
とto_a
の違いは暗黙的または暗黙的な変換かどうかという違い。*
による引数展開は明示的変換。
ruby - What's the difference between to_a and to_ary? - Stack Overflow
引用をストックしました
引用するにはまずログインしてください
引用をストックできませんでした。再度お試しください
限定公開記事のため引用できません。