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

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

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

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

Ruby

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

Q&A

解決済

1回答

2272閲覧

RubyのCSV::Tableクラスで作成したカラム`table[0][0]`に値が代入され値が変わる理由

hanzoo

総合スコア28

CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

Ruby

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

0グッド

1クリップ

投稿2017/05/04 13:15

編集2017/05/04 13:47

RubyのCSV::Tableクラスで作成したテーブルのカラムに値100を代入する場合、table[:id][0] = 100は値の代入不可ですが、table[0][0] = 100では値が代入出来るのはなぜでしょうか。

値が代入できることを疑問に思った理由は、instance method CSV::Table#[] (Ruby 2.4.0)で以下の文を見つけたためです。

値の配列を返します。この配列を変更しても元のデータには何の影響もありません。

上記の引用の内容を読み、例えば、後述するCSVファイルが合った場合、table[0][0] = 100table[:id][0] = 100のどちらを実行してもtableの値は変わらないはずではないかと考えたのですが、以下のように実行した場合、table[0][0] = 100を実行すると値が変わってしまいます。しかし、table[:id][0] = 100は値に変化はありません。

用意したCSVファイル

csv

1# data.csv 2 3id,name,age 41,hattori,25 52,hanzoo,35

Pryを実行

$ pry

Terminal

1[1] pry(main)> require 'csv' 2=> true 3 4[2] pry(main)> table = CSV.table('data.csv') 5=> #<CSV::Table mode:col_or_row row_count:3> 6 7[3] pry(main)> puts table 8id,name,age 91,hattori,25 102,hanzoo,35 11=> nil 12 13# 値の代入が出来ない 14 15[4] pry(main)> table[:id][0] = 100 16=> 100 17 18[5] pry(main)> puts table 19id,name,age 201,hattori,25 212,hanzoo,35 22=> nil 23 24# 値の代入が出来る 25 26[6] pry(main)> table[0][0] = 100 27=> 100 28 29[7] pry(main)> puts table 30id,name,age 31100,hattor,25 322,hanzoo,35 33=> nil

追加補足

URLで申し訳ないのですが、元は下記URLの疑問の延長となっています。
Ruby - RubyのCSV::Tableクラスで作成したカラムtable[:id][0]に値が代入できないのはなぜですか(74846)|teratail

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

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

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

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

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

guest

回答1

0

ベストアンサー

Ruby

1table[:id].class 2=> Array 3table[:id] 4=> [1, 2] 5table[0].class 6=> CSV::Row 7table[0] 8=> #<CSV::Row id:1 name:"hattori" age:25>

とするとわかります。値を代入しようとするオブジェクトが違うのです。
table[argv]はインデックスかヘッダかで振る舞いが違っています。
ヘッダを指定すると@table.map { |row| row[index_or_header] }に渡されて、Arrayオブジェクトを生成して戻り値にします。
つまり、CSV::Tableインスタンスとは独立した別のインスタンスに値を代入していることになります。
インデックスを指定すると、CSV::Tableインスタンスが内包しているCSV::Rowインスタンスを戻り値にします。
つまり、CSV::Tableインスタンスそのものに値を代入していることになります。

投稿2017/05/04 16:52

編集2017/05/04 16:56
NCC1701

総合スコア1680

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

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

hanzoo

2017/05/05 07:22

確認手順や得た結果から考えることまで詳しく説明頂き、大変勉強になりました。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問