2017-03-24 6 views
0

fooにアクセスするにはどうすればGetVar.print_fooにありますか?Rubyモジュールはローカル変数にアクセスできません

foo = "test" 

module GetVar 
    def self.print_foo 
     puts foo 
    end 
end 

GetVar.print_foo 

私は一定のFOOfooを変更することで、それが仕事を得ることができたが、これはハックの詳細です、私はよりよい解決策を探しています。また、fooをインスタンス変数@fooにすることもできません。

+1

あなたは 'デフself.fooを追加することができます。 "テスト";モジュール内の「終わり」にある。 –

+0

@CarySwovelandいいえ、その原因私はfooを定義していません - 実際には 'verify_recaptcha'ですが、別の宝石から来ています。私はrecaptcha gemを使用していますが、 'verify_recaptcha'を呼び出すヘルパーメソッドを作成しようとしていますが、ヘルパー関数はrecaptcha gemから必要な機能を持たない新しいスコープを作成します。 –

+0

@ChristianJuthローカル変数は、メソッドへの現在の呼び出しに対してローカルであり、トップレベルのバインディングに対してローカルであれば、トップレベルのバインディングに対してローカルです。他の場所にはアクセスできないし、アクセスすべきでもない。 – Aetherus

答えて

0

使用class_eval

class A 
    @foo = "test" 
end 
module GetVar 
    def self.print_foo 
     A.class_eval do 
     puts @foo 
     end 
    end 
end 
GetVar.print_foo 
#=> "test" 

か、この質問を参照してくださいスコープ

foo = "test" 
GetVar = Module.new do 
    # define a class method 
    define_singleton_method :print_foo do 
    puts foo 
    end 
end 
GetVar.print_foo 
#=> "test" 

を平坦化:How to understand the difference between class_eval() and instance_eval()?

0

単純な答えです:いいえ、ローカル変数にアクセスする方法はありませんfooスクリプトのスコープではprint_fooメソッドのメソッドスコープから取得します。 fooはローカル変数ですが、ローカル変数は定義されているスコープに対してローカルなので、結局はローカル変数と呼ばれています。

fooは、スクリプトスコープで定義されています。 print_fooのメソッドスコープには定義されていませんが、print_fooからはアクセスできません。

Rubyには、スクリプト、モジュール/クラス定義、メソッド定義、ラムダリテラル/ブロックボディという4つのローカル変数スコープがあります。これら4つのうち、スクリプトスコープ、モジュール/クラススコープ、およびメソッドスコープは新しいスコープを作成します。ラムダリテラルとブロック、これらの2つは、周囲のレキシカルスコープからローカル変数にアクセスできる入れ子スコープを作成します。

ので、print_foofooへのアクセスを取得する唯一の方法は、print_fooはブロック内で、すなわち、ネストされたスコープで定義されていることを確認することで、全ての周囲のスコープもブロックされていること。ありがたいことに、ブロックをとり、また、ブロックかかりModule::newと呼ばれるモジュールを定義するための方法があるModule#define_method呼び出されるメソッドを定義する方法(又はこの場合には実際Object#define_singleton_method)がある。

とにかくアクセスにありfooからGetVar.print_foo

foo = "test" 

GetVar = Module.new do 
    define_singleton_method(:print_foo) do puts foo end 
end 

GetVar.print_foo 
# test 

実は、私たちもModule::newのブロック形式を必要としない:

foo = "test" 

GetVar = Module.new.tap do |m| m.define_singleton_method(:print_foo) do puts foo end end 

GetVar.print_foo 
# test 
関連する問題