質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Q&A

解決済

2回答

2753閲覧

配列の中のハッシュをto_aで表示

shirou

総合スコア15

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

0グッド

1クリップ

投稿2018/07/15 09:34

期待結果

この結果が得られるメソッドの定義について
clever_print(["Ruby"], "the", ["Programming", "Language"])
=> Ruby the Programming Language

clever_print(["Agile", "Web", "Development"], "with", { :Rails => 3.0 })
=> Agile Web Development with Rails 3.0
問題原典-ミニツクより

模範回答コードより生じたエラー・下自作コードの場合

ruby

1Main.rb:8:in `block in clever_print': undefined method `to_a' for "the":String (NoMethodError)

ruby

1Ruby the Programming Language 2Agile Web Development with {:Rails=>3.0}

模範回答コード

ruby

1def clever_print(*args) 2 converted = [] 3 args.each { |arg| converted << arg.to_a } 4 puts converted.join(" ") 5end

### 自作コード

ruby

1def clever_print(*num) 2 array = [] 3 array << num.to_a 4 puts array.join(" ") 5end

試したこと

メソッドより受け取った引数を配列に直した上で、配列の要素として出力すればto_aメソッドはレシーバ自身を返す為に、期待結果に至るだろうと予想。
残念ながらハッシュは外れなかった為、ミニツクサイトにあった模範回答コードを試してみることに。
すると模範回答コードがエラーを吐き出してはありませんか・・
打つ手がなくなり質問に至ります。

補足情報(FW/ツールのバージョンなど)

実行環境はpaiza.io こちらです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

エラーの原因は、既にある回答の通りですが、

Ruby

1class String 2 def to_a 3 [self] 4 end 5end

とすれば、「模範解答」はとりあえず動きます。あんまり模範解答な気はしませんが。

趣旨をくんで書き直すとこんな感じでしょうか。

Ruby

1def clever_print(*args) 2 puts args.map{|x| x.respond_to?(:to_a) ? x.to_a : x}.join(" ") 3end

また、質問者のコードは、

Ruby

1 def clever_print(*args) 2 puts args.to_a.join(" ") 3 end

と同じです。

投稿2018/07/15 10:34

otn

総合スコア84423

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

shirou

2018/07/15 11:29

回答ありがとうざいます! ようやくなぜ頂いたコードで期待結果が得られるのか理解できました。 引数をそれぞれ取り出した上で直接to_aメソッドを用いると、文字列要素が含まれている箇所がエラーを起こす為、条件分岐で適用される箇所を分けたということ。 そして自作コードの場合では配列を取り出すeachもしくはmapメソッドの記述がない為に、[]だけを外す処理になっていたということですね。
otn

2018/07/15 12:15

Stringかどうかで判断せず、to_aメソッドを持っているかどうかで判断するのがRuby風です。他のto_aを持たないクラスであっても良いように。 joinによって、配列各要素に対してStringでないものはto_sが自動的に呼ばれます。 また質問者のコードは、結局 args.join(" ") と同じです。Arrayにto_aしても不変なので。
guest

0

Ruby 1.9でStringまわりの処理が変わったので、String#to_aは1.8.7以下のRubyにしかありません。ということで、参考にしたサイトがかなり古い可能性があります。

投稿2018/07/15 09:55

maisumakun

総合スコア145121

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2018/07/15 09:59

言語の基礎的な部分を古い参考資料で学ぼうとするのは、このようにトラブルになったり、今ならすんなりできることを回りくどく書いてあったりして、手間になるだけです。別なもので進めることをおすすめします。
maisumakun

2018/07/15 10:02

Rubyのバージョンは明記されていませんが、同じサイトのRailsのバージョンが2.3.8ということで、確実に古すぎます。
shirou

2018/07/15 10:36

Ruby versionはご指摘通り1.8.7以下の環境で書かれたサイトになります。 仰られる通り、参考サイトがかなり古いので別のサイトの利用に移行します。 回答ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問