40347


selfはメソッドの中で呼び出すと、メソッドを実行している、インスタンス自身となり、それはtomになります。tomのことをレシーバーといいます。tomにはUser.new('tom')というインスタンスが代入されいて、最終的にはselfはUser.newを指していることだと思います。

つまりは 「def initialize(name)メソッドはインスタンス変数を保持しており、
**.nameメソッドでアクセサを参照し保持されたインスタンス変数を見にいくから** 、  
hi I am tomになる」ということで宜しいでしょうか？

[code]

     class User
          attr_accessor :name
    
          def initialize(name)
            @name = name
          end
    
          def sayHi
            self　#self.nameがわからない
            puts "hi I am #{self.name}"#なぜself.nameでtomに？
          end
        end
    
        tom = User new("tom")
        tom.sayHi
    
[/code]

### 分かったこと

  1. p self → User:0x00000000057c4098 @name="tom"  
インスタンス変数を自動的に見ている。

  2. 1.の結果からselfはオブジェクトを見ている。


CC BY-SA 3.0
2017-12-17T23:03:19.653
40344
2017-12-19T04:52:16.097
2017-12-18T11:43:46.210
26076
26076
question
ruby
rubyのselfは何が言いたいのかわからない。


> tomにはUser.new('tom')というインスタンスが代入されいて、最終的にはselfはUser.newを指していることだと思います。

`User.new`を指すというか、`User.new`によって生成されたオブジェクトを指します。

このオブジェクトは`new`の引数として`"tom"`を渡しており、結果[initialize](https://docs.ruby-
lang.org/ja/latest/method/Object/i/initialize.html)メソッドに`"tom"`が渡ります。

少し書き換えて実験してみました

[code]

    class User
      attr_accessor :name
    
      def initialize(name)
        @name = name
      end
    
      def sayHi
        self #self.nameがわからない
        puts "#{@name}: hi I am #{self.name}"#なぜself.nameでtomに？
      end
    
      # selfを他のオブジェクトと比べてみる
      def eq?(obj)
        puts "#{self.name} == #{obj.name}: #{obj == self}"
      end
    end
    
    user_tom = User.new("tom")
    user_tom.sayHi
    # 以下ちょい蛇足self(レシーバー)とは何か実験してみる
    p user_tom
    user_tom.eq?(user_tom)
    user_tom.eq?(User.new("bob"))
    
[/code]

**追記**

> selfはなぜこれを使うのか？という疑問

逆にないと、常に記憶喪失な人に「お前はトムだが挨拶しろ」みたいになって不便だと思います

`self.name`じゃなくて`@name`でいいのでは？というのなら例が悪いかなと思います。

`self.name`じゃなくて`name`でいいのではないか？(暗黙のself)というのなら、好みですね

`name = "slime"` とした時にローカル変数なのかアクセッサの呼び出しなのか分からずに、  
ローカル変数への代入として処理されるRubyの仕様があるので  
個人的にはselfの省略は好きではないです。


CC BY-SA 3.0
2017-12-18T00:54:47.697
40347
2017-12-19T01:35:43.320
2017-12-19T01:35:43.320
26230
26230
40344
answer


ruby
はオブジェクト指向プログラミング言語です。関数は実は存在していなくって、ありとあらゆる関数っぽいものは、実は何かしらのメソッドです。メソッドのロジックを`def`などで記述している段階では、なので必ず暗黙的に今そのメソッドを実行しようとしているオブジェクトというものが想定できるはずです。これが
`self` です。

ruby は、メソッドのロジックにおいて、ローカル変数でない名前を発見すると、それはメソッドであると解釈して、 `self.メソッド`
を呼ぶんだな、と判断します。

[code]

    puts "hi I am #{self.name}"
    
[/code]

たとえば上記の puts は、 Object
クラスのプライベートメソッドです。(プライベートメソッドは、レシーバーを指定する形の呼び出しができないタイプのメソッドなので、 `self.puts
"hoge"` は実行できないですが。。)

* * *

attr_accessor は, ruby のメタプログラミング的な何かです。 `attr_accessor シンボル` の効用は、

[code]

    def シンボル
        @シンボル
    end
    
    def シンボル=(v)
        @シンボル = v
    end
    
[/code]

とざっくり等価です。 self.name は、 `name` メソッドが呼びだされ、その中でインスタンス変数が読み込まれ、返り値として取得されます。
`name` メソッドは、プライベートメソッドではないので、 self
を省略した形式でも呼び出すことができます。ちなみに、セッターメソッドは、その言語仕様的に、ローカル変数の代入と区別ができなくなってしまうので、これにかぎり、
`self.name = 値` の形式で記述する必要があります。


CC BY-SA 3.0
2017-12-19T04:52:16.097
40373
2017-12-19T04:52:16.097
754
40344
answer