私はRubyプログラミングを最後にしてからしばらくしていました。他の人のコードを見て、@
という関数でsigilを参照しています(ではありません。メソッド - クラス定義外)。インスタンスメンバー。Rubyの機能の中で、どのようなスコープが "at"記号(@)ですか?
モジュールは機能していますか?self
は機能していますか?
私はRubyプログラミングを最後にしてからしばらくしていました。他の人のコードを見て、@
という関数でsigilを参照しています(ではありません。メソッド - クラス定義外)。インスタンスメンバー。Rubyの機能の中で、どのようなスコープが "at"記号(@)ですか?
モジュールは機能していますか?self
は機能していますか?
、あなたは少し奇妙な場所にいますまたはそのような関数内で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
を宣言することでこの問題を回避こそこそすることができますが、私はこれが好きかわかりません!奇妙なことに、irb
の中にトップレベルのメソッドを定義した場合は、それをpublic宣言することなく、クラスメソッド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
(及びインスタンス変数が属するこうしてコンテキスト)で、どこでも利用できるようになりますが、可変インスタンス変数になることを意味します。明示的に宣言されたクラスの一部ではないように思えるので、Chuckが指摘したように、メインオブジェクト内で利用可能になります。それは、簡単に例で示されています:グローバル「メイン」スペース(あなたがirb
を実行したときにプロンプトが表示され、:トップレベルの機能(実際にはまだ法)で
$ 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
さて、モジュールレベルの関数内で@identは$ identを別の方法で表していますか? – cdleary
いいえ、それはモジュールの@identインスタンス変数を設定します(Rubyではモジュールもオブジェクトであり、独自のivarsを持つことができます)。 "@ident = something"は、現時点の "self"の@identインスタンス変数を設定します。 – Chuck
だから、グローバルは本当にグローバル(インタープリタにバインドされている)であり、モジュールの範囲に限定されません。 – cdleary