0

変数にアクセスするとき、Ruby のフォールバック メカニズムは最初にローカル変数を検索し、見つからない場合は自動的に適用selfしてインスタンス変数を検索します。ただし、次のコードは機能しません。

class My
  def init
    @abc = "abc"
  end

  def pt
    puts abc
  end
end

ptインスタンスを呼び出そうとすると、次のエラー メッセージが表示されました。

2.0.0-p247 :009 > my = My.new
 => #<My:0x007f9b5a1b1000> 
2.0.0-p247 :010 > my.init
 => "abc" 
2.0.0-p247 :011 > my.pt
NameError: undefined local variable or method `abc' for #<My:0x007f9b5a1b1000 @abc="abc">

ただし、@abcDOES はオブジェクトのインスタンス変数として存在します。

2.0.0-p247 :012 > my.instance_variables
=> [:@abc] 

では、なぜここでpt見つからないのでしょうか。abcローカルで定義されていないため、インスタンス変数を自動的に検索して出力するべきではありませんか?

ノート:

を使用するとうまくいくことはわかってputs @abcいますが、これは私の質問のポイントではありません。私の質問は、Ruby のフォールバック メカニズムについてです。このコードは機能します:

2.0.0-p247 :079 > class My
2.0.0-p247 :080?>     def initialize(param)
2.0.0-p247 :081?>         @abc = param
2.0.0-p247 :082?>       end
2.0.0-p247 :083?>   
2.0.0-p247 :084 >       def printabc
2.0.0-p247 :085?>         puts abc
2.0.0-p247 :086?>       end
2.0.0-p247 :087?>   end

2.0.0-p247 :089 > My.new("haha").printabc
haha

前のケースでは機能しないのに、後者では機能する理由がわかりません。

4

1 に答える 1

3

以下のようにしてください(@シンボルを逃した)

def pt
    puts @abc
end

では、なぜ pt はここで abc を見つけられないのでしょうか?

attr_accessorまたはを使用すると、期待したことが起こりますattr_reader。同じものについては、以下を参照してください。この場合、ruby は最初に という名前でローカル変数が作成されているabcかどうかをチェックしますが、見つからない場合は、( )abcにメッセージabcを渡して、名前で定義されているメソッドがあるかどうかをチェックします。メソッドを定義するようになりました(これは の 2 つのメソッドの 1 つでもあります)。したがって、エラーはありません。 の出力が得られます。selfself.abcattr_readerdef abc; @abc ;endattr_accessor@abc

class My
  attr_accessor :abc
  def init
    @abc = "abc"
  end

  def pt
    puts abc
  end
end

my = My.new
my.init # => "abc"
my.pt
# >> abc

onlyのような裸の呼び出しがあるfoo場合、Ruby は常に最初にそれがローカル変数かどうかをチェックします。見つかったスコープ内に名前を持つローカル変数が見つからない場合fooは、それがメソッドであるかどうかを確認します。事実を理解するには、以下の 1 つのデモ例を参照してください。

x = 10
def x ;11;end
x # => 10
于 2013-11-14T20:50:57.333 に答える