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

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

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

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

Q&A

解決済

1回答

1204閲覧

arr = 1..3 ←Arrayクラスを使わずに範囲演算子を変数に入れた場合、配列として扱えるのか

退会済みユーザー

退会済みユーザー

総合スコア0

Ruby

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

0グッド

0クリップ

投稿2016/10/15 01:43

編集2016/10/15 01:52

ruby

1arr1 = [1,2,3] 2arr2 = 1..3 3 4#① 5#arr2が配列化されていないのはなんとなくわかる。 6#明示してないので。 7p arr1 8p arr2 9 10 11#② 12#なぜかarr2が配列のように扱えている。 13for i in arr1 14print "#{i}," 15end 16 17puts "\n" 18for i in arr2 19 print "#{i}," 20end 21 22 23 24puts "\n" 25 26 27#③ 28#arr2[0]は配列化されていないのかエラーになります。 29p arr1[0] 30p arr2[0] 31 32

範囲演算子をどう扱えばよいのかがまだわかっていません。

①pでarr2を出力してみると配列化されていない
②for文ではarr2の要素を順番に取り出せるので配列化されているように見える
③arr2[0]のようにアクセスしようとするとエラーになるので配列化されていないように見える

①、②、③でなぜ配列化されているように見えたり見えなかったりするのでしょうか。

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

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

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

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

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

guest

回答1

0

ベストアンサー

1..3はRangeのオブジェクトです。Rangeはeachメソッドを持ち、Enmuerableをmix-inしています。これにより、Arrayでよく使うようなメソッドがいくつか使用でいます。しかし、Arrayそのものではないため、Array特有のメソッドは使用できません。

①pでarr2を出力してみると配列化されていない

ArrayではなくRangeですので、pでの出力は異なります。

②for文ではarr2の要素を順番に取り出せるので配列化されているように見える

for文は内部でeachメソッドを使っています。ブロックスコープを作るか作らないかというたった一つの違いを除き下記と同じです。

Ruby

1arr2.each do |i| 2print "#{i}," 3end

Rangeはeachメソッドがありますので、問題なくfor文で使用できます。

③arr2[0]のようにアクセスしようとするとエラーになるので配列化されていないように見える

Array#[]はArray特有のメソッドで有り、Enumerableにはありません。arr2.firstのようにEnumerableのメソッドを使えば取得できます。

Rangeは、順番にアクセスできるもの、という型であるため、Arrayのように添字アクセスや特定の一を変更などのようなメソッドは用意されていません。しかし、もし、完全にArrayにしてしまいたい場合は、arr2.to_aとすることでArrayにできます。連続する数字のArrayを手っ取り早く作りたいと言った場合は、(1..3).to_aなどとする場合があります。

投稿2016/10/15 01:55

編集2016/10/15 02:00
raccy

総合スコア21735

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

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

退会済みユーザー

退会済みユーザー

2016/10/15 02:14

Enmuerableを軽く調べたところ「繰り返しを行なうクラスのための Mix-in。」とありました。 繰り返しを行うためのものであることはなんとなく理解できたのですが、配列化する/しないというのはまた別の話ではないのでしょうか。 arr2 = 1..3とした時点では配列化されていないが、for文に渡した時点でEnmuerableの効果で配列化される、というのが納得できないです。 あくまで範囲を指定するためのものであって、私の期待する挙動としては②もエラーになるべきと考えています。 ちなみに(1..3).to_a これはなんとなく納得できます。to_aは名前からしてarrayにする為のものですから、間違えようがないし便利機能として良いものだと思います。 for文はarray化する雰囲気が伝わってこないので、いきなりそんなことされても困ります。 時間が経てば理解して納得できるようになるかもしれないのですが、今の段階では上記が率直な感想です。 raccyさんに文句言ってもしょうがないのですが。。すみません。
raccy

2016/10/15 02:24 編集

for文は配列専用の構文ではありません。for文は内部で`each`メソッドを呼び出しているだけであり、内部で配列化しているわけでも、配列として扱っているわけでもありません。`each`メソッドがある全てのクラスで使用できます。
退会済みユーザー

退会済みユーザー

2016/10/15 02:40

なんとなく理解できてきました。eachメソッドは ①Arrayクラスのインスタンス?の要素を一つずつ取り出せる ②Rangeクラスのインスタンス?をカウントアップ/ダウンして”読み取る”ことができ、読み取った値をブロック変数に渡すことができる。 今回のケースは②に該当する。 配列の各要素が出力されたわけではなく、あくまでブロック変数に渡されたRangeの値が出力されただけ、 ということでしょうか。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問