なかなか理解できるように説明するのは難しいですね。
⑥のところで、initialaizeメソッドに進む部分とクラスメソッド戻り値をusesrsに入れる部分とに分かれるように見えて混乱しています。
順番的にはUser.new(name) ←⑤
でオブジェクト生成、生成時にdef initialize(name) ←⑥
が実行され@name = name ←⑦
が実行、それをnames.map do |name| ←④
のusersの配列の数だけ繰り返し、全ループが完了したらusers = User.create_users(names) ←②
のusers変数に値を格納します。
番号で言うと②③④[⑤⑥⑦(Alice)][⑤⑥⑦(Bob)][⑤⑥⑦(Carol)]で、その次に配列オブジェクトをusersに入れる。
になります。
なので、「配列オブジェクトをusersに入れる。」は⑥ではなくて⑧になると思います。
ruby
1class User
2 def initialize(name) ←⑥ (⑤のuser.newのときに呼ばれる)
3 @name = name ←⑦
4 end
5クラス名.メソッド名
6# self.を付けるとクラスメソッドになる
7 def self.create_users(names) ←③
8 names.map do |name| ←④
9 User.new(name) ←⑤
10 end
11end
12# これはインスタンスメソッド
13 def hello ← ⑪
14 "Hello, I am #{@name}." ⑫
15 end
16end
17names = ['Alice', 'Bob', 'Carol'] ←①
18# クラスメソッドの呼び出し
19users = User.create_users(names) ←② ←⑧配列オブジェクトをusersに入れる。
20users.each do |user| ←⑨
21# インスタンスメソッドの呼び出し
22 puts user.hello ←⑩ ←⑬putsで値を表示
23end
24#=> Hello, I am Alice.
25# Hello, I am Bob.
26# Hello, I am Carol.
ループの部分をもう少し分かりやすくすると以下の様なコードになるかと思います。
ruby
1def self.create_users(names) ←③
2 userList = names.map do |name| ←④
3 return User.new(name) ←⑤
4 end
5
6 return userList
7end
8
9# 多分上記のコードは正常に動作しないので、現実的なものを書くと
10def self.create_users(names) ←③
11 userList= names.map { |name| ←④
12 return User.new(name) ←⑤
13 }
14
15 return userList
16end
rubyはreturnを省略が可能で、省略された場合一番最後のコードが返却されます。
names.map
に関してはUser.new(name)
のリストが返却、def self.create_users(names)
に関しては、names.map
の結果つまりUser.new(name)
のリストが返却されます。
⑥のところでは、create_user(names)の戻り値として、 ['Alice', 'Bob', 'Carol']が戻ると理解しています。
自分の理解だと少し違って、戻り値は以下だと認識しています。
[User<xxxxx>, User<yyyy>, User<zzzz>]
(多分インスタンスにIDが振られて表示される記憶です)
つまり、①で定義した['Alice', 'Bob', 'Carol']それぞれのUserインスタンスという理解です。
(既存の回答はわかりやすいように記述したのかもしれません。個人的にはnewで生成されたインスタンスが返却されてusersに格納される気がします)
試しにusers = User.create_users(names)
とusers.each do |user|
の間またはループ内のputs user.hello
の上にprint(p)を入れてみてはどうでしょうか。
多分Userのインスタンスが入っていると思います。
ruby
1names = ['Alice', 'Bob', 'Carol'] ←①
2
3# クラスメソッドの呼び出し
4users = User.create_users(names) ←② ←⑥配列オブジェクトをusersに入れる。# ***追記①***
5p users[0]
6
7users.each do |user| ←⑦
8# インスタンスメソッドの呼び出し
9 # ***追記②***
10 p user
11 puts user.hello ←⑧
12end
13
オブジェクト指向の書籍等でよく表現されているように、クラスは設計図、実態はオブジェクトなので、Userクラスの中でUser.new()をしている為、newしたその都度インスタンスが生成され、最初にinitialize
関数が実行されます。
@nameは'Alice' → 'Bob' → ´Carol' と上書きを重ねて、’Carol'しか残っていないように思えます。
この考え方は、create_users(names)の中でclass Userの@nameの値にデータが入っているイメージをされているのではないでしょうか。
そうではなくて、Userクラスはあくまでも設計図で、コードではnewでインスタンスを個別に生成している為、上書きはされません。
他の言い方をすると、class User
は内部でUser.new(name)
を呼び出しています。
自身のクラス内で自身のオブジェクトを生成することはあると思います。
色々な方向から説明をしてみましたが、どうでしょうか。
(内容間違えていたらすみません)