1

私が最後に Ruby プログラミングを行ってからしばらく経ちました -- 他の誰かのコードを見る@と、関数 (メソッドではなく、クラス定義の外部) にシジルがあり、インスタンス メンバーにスコープされていることがわかりました。

selfモジュールは関数で暗示されていますか?

4

4 に答える 4

3

トップレベルの関数 (実際にはまだメソッドです) では、少し奇妙な場所にいます: グローバルな「メイン」スペース (実行時にプロンプ​​トを参照するirbか、そのような関数の内部を調べてみてくださいself) だけでなく、これらの関数もObjectクラス内でプライベート メソッドとして定義されます。

$ cat foo
def foo
  p self
  p self.class
  puts 'foo'
end

foo
Object.foo

$ ruby foo
main
Object
foo
foo:8: private method `foo' called for Object:Class (NoMethodError)
$ 

これらのメソッドを明示的に宣言することでこれをこっそり回避できますが、これpublicが好きかどうかはわかりません! 興味深いことに、 内でトップレベルのメソッドを定義すると、クラス メソッドを public と宣言せずirbに呼び出すことができます。Object#foo

したがって、これは一種の「ハッキングされた暗黙のメイン名前空間Object(しかし誰にも言わないでください)」です。@fooトップレベル関数内で定義されたものは、プレーンな古い属性としてオブジェクト内で使用できます。並べ替え。トップレベルのメソッドが設定され@fooていて、スコープなしで呼び出すと、固有のようなmain名前空間で宣言されますが、クラス メソッドを呼び出すと、のスペースに表示されObjectます。@fooObject

もう一つの例:

public
def set_foo
  @foo = 'foo'
end

def get_foo
  @foo
end

def Object.get_foo_again
  @foo
end

set_foo
p get_foo
p Object.get_foo_again

Object.set_foo
p Object.get_foo_again

与える

"foo"  # @foo set in main
nil    # @foo nil in Object  
"foo"  # @foo in Object

逆も適用されます。

于 2009-05-08T01:08:37.690 に答える
2

これが「メソッドではなく関数」であるという仮定は間違っています。すべてのRubyコードは、あるオブジェクトのコンテキスト内で発生します。「グローバル」コンテキストは、呼び出されるオブジェクトです(信じられない場合はmain試してください)。ruby -e "puts self"最上位スコープで定義されたメソッドは、Objectのインスタンスメソッドになります。これは、メソッドが呼び出される場所に応じて、メソッドがどこでも使用できることを意味しselfます(したがって、インスタンス変数が属するコンテキスト)。

于 2009-05-08T00:42:05.973 に答える
1

私はそれをモジュールにスコープすると思います。

于 2009-05-08T00:33:39.490 に答える
1

@ は、変数をインスタンス変数にします。明示的に宣言されたクラスの一部ではないように聞こえるため、チャックが指摘したように、メイン オブジェクト内で使用できるようになります。例で説明すると簡単です:

$ irb
irb(main):001:0> @var = 1
=> 1
irb(main):002:0> class New
irb(main):003:1>   def test
irb(main):004:2>     puts @var
irb(main):005:2>   end
irb(main):006:1> end
=> nil
irb(main):007:0> test = New.new
=> #<New:0xb7ccbc14>
irb(main):008:0> test.test
nil
=> nil
irb(main):009:0> def test2
irb(main):010:1>   puts @var
irb(main):011:1> end
=> nil
irb(main):012:0> test2
1
=> nil
于 2009-05-08T01:05:14.017 に答える