1

さて、特定のライブラリをロードするのに少し問題があります。ライブラリがスコープ外になる可能性があります。この場合、それは何が起こっているのですか?

主な問題:グローバルスコープで使用できるように、関数にライブラリが必要です。例:

   class Foo
      def bar
         require 'twitter_oauth'
         #....
      end
      def bar_2
         TwitterOAuth::Client.new(
            :consumer_key => 'asdasdasd',
            :consumer_secret => 'sadasdasdasdasd'
            )
      end
    end 

   temp = Foo.new
   temp.bar_2

今私の問題を解決するために、私はそれをグローバルスコープにバインドするevalを実行しようとしています...このように

    $Global_Binding = binding
   class Foo
      def bar
         eval "require 'twitter_oauth'", $Global_Binding
         #....
      end
      def bar_2
         TwitterOAuth::Client.new(
            :consumer_key => 'asdasdasd',
            :consumer_secret => 'sadasdasdasdasd'
            )
      end
    end 

   temp = Foo.new
   temp.bar_2

しかし、それはうまくいかなかったようです...何かアイデアはありますか?これを行うためのより良い方法はありますか?

4

1 に答える 1

1

A.
ファイルtest_top_level.rb:

puts '    (in TestTopLevel ...)'
class TestTopLevel
end

RSpecを使用してファイルttl.rbをテストします。

# This test ensures that an included module is always processed at the top level,
# even if the include statement is deep inside a nesting of classes/modules.

describe 'require inside nested classes/modules' do
#        =======================================

    it 'is always evaluated at the top level' do
        module Inner
            class Inner
                require 'test_top_level'
            end
        end

        if RUBY_VERSION[0..2] == '1.8'
        then
            Module.constants.should include('TestTopLevel')
        else
            Module.constants.should include(:TestTopLevel)
        end
    end
end

実行:

$ rspec --format nested ttl.rb 

require inside nested classes/modules
    (in TestTopLevel ...)
  is always evaluated at the top level

Finished in 0.0196 seconds
1 example, 0 failures

B.
不要なrequireステートメントを処理したくない場合は、代わりにautoloadを使用できます。autoload( name, file_name )モジュール名に初めてアクセスするときに(Object#requireを使用して)ロードされるfile_nameを登録します。

ファイルtwitter_oauth.rb:

module TwitterOAuth
    class Client
        def initialize
            puts "hello from #{self}"
        end
    end
end

ファイルt.rb:

p Module.constants.sort.grep(/^T/)

class Foo
    puts "in class #{self.name}"

    autoload :TwitterOAuth, 'twitter_oauth'

    def bar_2
        puts 'in bar2'
        TwitterOAuth::Client.new
    end
end 

temp = Foo.new
puts 'about to send bar_2'
temp.bar_2

p Module.constants.sort.grep(/^T/)

Ruby 1.8.6での実行:

$ ruby -w t.rb 
["TOPLEVEL_BINDING", "TRUE", "Thread", "ThreadError", "ThreadGroup", "Time", "TrueClass", "TypeError"]
in class Foo
about to send bar_2
in bar2
hello from #<TwitterOAuth::Client:0x10806d700>
["TOPLEVEL_BINDING", "TRUE", "Thread", "ThreadError", "ThreadGroup", "Time", "TrueClass", "TwitterOAuth", "TypeError"]
于 2012-12-31T04:10:20.163 に答える