私が最後に Ruby プログラミングを行ってからしばらく経ちました -- 他の誰かのコードを見る@
と、関数 (メソッドではなく、クラス定義の外部) にシジルがあり、インスタンス メンバーにスコープされていることがわかりました。
self
モジュールは関数で暗示されていますか?
トップレベルの関数 (実際にはまだメソッドです) では、少し奇妙な場所にいます: グローバルな「メイン」スペース (実行時にプロンプトを参照する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
ます。@foo
Object
もう一つの例:
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
逆も適用されます。
これが「メソッドではなく関数」であるという仮定は間違っています。すべてのRubyコードは、あるオブジェクトのコンテキスト内で発生します。「グローバル」コンテキストは、呼び出されるオブジェクトです(信じられない場合はmain
試してください)。ruby -e "puts self"
最上位スコープで定義されたメソッドは、Objectのインスタンスメソッドになります。これは、メソッドが呼び出される場所に応じて、メソッドがどこでも使用できることを意味しself
ます(したがって、インスタンス変数が属するコンテキスト)。
私はそれをモジュールにスコープすると思います。
@ は、変数をインスタンス変数にします。明示的に宣言されたクラスの一部ではないように聞こえるため、チャックが指摘したように、メイン オブジェクト内で使用できるようになります。例で説明すると簡単です:
$ 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