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

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

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

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

Q&A

解決済

2回答

1636閲覧

添字メソッド、indexについて

yusn

総合スコア24

Ruby

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

0グッド

0クリップ

投稿2018/11/02 15:40

前提・実現したいこと

indexの使い方を理解したいと思って質問しました

該当のソースコード

class Point attr_accessor :x, :y def initialize(x,y) @x,@y=x,y end def [] (index) case index when 0 x when 1 y else raise ArugmentError,"out of range '#{index}'" end end def []=(index,val) case index when 0 self.x=val when 1 self.y=val else raise ArugmentError, "out of range '#{index}'" end end end p Point.new(3,6)[0] #=>3 p Point.new(3,6)[1]=2 #=>2 p Point.new(3,6)[1] #=>2? p Point.new(3,6)[2] #=>Arugmenterror

(1)def []=(index,val)の()内にvalが入った理由がわかりません。
また、
(2)whenの後のself.x=valの意味はどういった意味なのか、どういった理由で入れなければならないのか、
(3)なぜArugmentErrorを設定しないといけないのか、
(4)p列の3行目、p Point.new(3,6)[1]の返しが6になってしまうのはなぜか。
以上の4つについて教えてほしいです。

試したこと

(4)に関しては何回か試してみましたが6になりました。

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

始めて1週間くらいなので質問自体が正しい質問かすらわかりませんが答えてくれるとありがたいです!

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

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

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

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

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

guest

回答2

0

ベストアンサー

デバッグ用にメッセージを出力させてみるので実行させて観察してみてください

ruby

1class Point 2 attr_accessor :x, :y 3 4 def initialize(x,y) 5 puts "Point##{__id__.to_s(36)}を作ります" 6 @x,@y=x,y 7 end 8 9 10 def [] (index) 11 puts "Point##{__id__.to_s(36)}[#{index}]を取得します" 12 case index 13 when 0 14 x 15 when 1 16 y 17 else 18 raise ArugmentError,"out of range '#{index}'" 19 end 20 end 21 22 def []=(index,val) 23 puts "Point##{__id__.to_s(36)}[#{index}]を#{val}で書き換えます" 24 case index 25 when 0 26 self.x=val 27 when 1 28 self.y=val 29 else 30 raise ArugmentError, "out of range '#{index}'" 31 end 32 end 33end 34 35p Point.new(3,6)[0] #=>3 36p Point.new(3,6)[1]=2 #=>2 37p Point.new(3,6)[1] #=>2? 38point = Point.new(3,6) 39p point[1] #=> 6 40p point[1] = 2 #=> 2 41p point[1] #=> 2 42p Point.new(3,6)[2] #=>Arugmenterror

結果は当環境ですと

Point#dv664を作ります Point#dv664[0]を取得します 3 Point#dv588を作ります Point#dv588[1]を2で書き換えます 2 Point#dv4wkを作ります Point#dv4wk[1]を取得します 6 Point#dv2t0を作ります Point#dv2t0[1]を取得します 6 Point#dv2t0[1]を2で書き換えます 2 Point#dv2t0[1]を取得します 2 Point#dv22cを作ります Point#dv22c[2]を取得します Traceback (most recent call last): 1: from -:42:in `<main>' -:18:in `[]': uninitialized constant Point::ArugmentError (NameError) Did you mean? ArgumentError

となりました。


(1)def []=(index,val)の()内にvalが入った理由がわかりません。

これに関してはそういうもの、としか言いようがないです。

(2)whenの後のself.x=valの意味はどういった意味なのか、どういった理由で入れなければならないのか、

attr_accessorによって定義したx=メソッドを呼び出しています。

(3)なぜArugmentErrorを設定しないといけないのか、

ArgumentErrorの間違いだとは思いますが、逆に何を返せばいいと思いますか?
xとyの2つの値しかないので返せる値がない のが正解だと私は思いますし
できることなら[2]などという呼び出しは間違ってますよ と教えてあげた方が親切ですね

(4)p列の3行目、p Point.new(3,6)[1]の返しが6になってしまうのはなぜか。

Point.newする度に新しいインスタンスが作られるからです。

投稿2018/11/02 16:24

asm

総合スコア15147

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

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

yusn

2018/11/03 06:01

わかりやすい回答ありがとうございました! プログラミングには、必ず必要でなくてもあったほうがいいという考え方もあるんですね! とても勉強になりました!
guest

0

(1)def []=(index,val)の()内にvalが入った理由がわかりません。
(2)whenの後のself.x=valの意味はどういった意味なのか、どういった理由で入れなければならないのか、

def [] (index) が値を取り出す処理で、呼び出す時は foo[0] といった感じで書きます。
def [] (index, val) が値を書き込む処理で、呼び出す時は foo[0] = 100 といった感じで書きます。
内部的にインスタンス変数 x, y に値を設定しているので、書き込み時は self.x や self.y に値を代入します。

(3)なぜArugmentErrorを設定しないといけないのか、

設定しないといけないなんてことはなく、別に無くてもいいです。
配列の範囲外にアクセスした時はエラーを出した方が、バグの早期発見に繋がって有益ではあります。

(4)p列の3行目、p Point.new(3,6)[1]の返しが6になってしまうのはなぜか。

Point.new(3,6) とするたびに新しいインスタンスが生成され、これらはインスタンス変数を共有しないからです。
次のように、いったん変数に格納すれば分かりやすいでしょうか。

foo = Point.new(3,6) bar = Point.new(3,6) foo[1] = 2 p foo[1] #=>2 p bar[1] #=>6

投稿2018/11/02 16:18

set0gut1

総合スコア2413

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

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

yusn

2018/11/03 06:04

回答ありがとうございました! おかげさまで悩んでいたvalについて理解できました! indexを呼び出すときのメソッドはfooという決まりはあるのでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問