2017-08-31 37 views
1

下面的Pry會話是莫名其妙的。我打電話給const_get,AFAIK得到一個常數,不知怎的,require被調用(並失敗並報錯)。但它不能是一個const_missing掛鉤,因爲定義了常量,如通過查看constants方法的輸出(並且還通過查看返回值const_defined?)可以看出(constantsconst_get均不是單調形式) :const_get如何產生副作用?

bash-3.2$ pry 
[1] pry(main)> require 'rack' # rack-2.0.3 installed 
=> true 
[2] pry(main)> Rack::Session 
=> Rack::Session 
[3] pry(main)> Rack::Session.constants 
=> [:Cookie, :Pool, :Memcache] 
[4] pry(main)> Rack::Session.const_defined?(:Memcache) 
=> true 
[5] pry(main)> Rack::Session.const_get(:Memcache) 
LoadError: cannot load such file -- memcache 
from /Users/user/.rbenv/versions/2.3.4/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require' 
[6] pry(main)> wtf???? 
Exception: LoadError: cannot load such file -- memcache 
-- 
0: /Users/user/.rbenv/versions/2.3.4/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require' 
1: /Users/user/.rbenv/versions/2.3.4/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require' 
2: /Users/user/.rbenv/versions/2.3.4/lib/ruby/gems/2.3.0/gems/rack-2.0.3/lib/rack/session/memcache.rb:4:in `<top (required)>' 
3: /Users/user/.rbenv/versions/2.3.4/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require' 
4: /Users/user/.rbenv/versions/2.3.4/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require' 
5: (pry):4:in `const_get' 
6: (pry):4:in `__pry__' 
7: /Users/user/.rbenv/versions/2.3.4/lib/ruby/gems/2.3.0/gems/pry-0.10.4/lib/pry/pry_instance.rb:355:in `eval' 
8: /Users/user/.rbenv/versions/2.3.4/lib/ruby/gems/2.3.0/gems/pry-0.10.4/lib/pry/pry_instance.rb:355:in `evaluate_ruby' 
9: /Users/user/.rbenv/versions/2.3.4/lib/ruby/gems/2.3.0/gems/pry-0.10.4/lib/pry/pry_instance.rb:323:in `handle_line' 
10: /Users/user/.rbenv/versions/2.3.4/lib/ruby/gems/2.3.0/gems/pry-0.10.4/lib/pry/pry_instance.rb:243:in `block (2 levels) in eval' 
11: /Users/user/.rbenv/versions/2.3.4/lib/ruby/gems/2.3.0/gems/pry-0.10.4/lib/pry/pry_instance.rb:242:in `catch' 
12: /Users/user/.rbenv/versions/2.3.4/lib/ruby/gems/2.3.0/gems/pry-0.10.4/lib/pry/pry_instance.rb:242:in `block in eval' 
13: /Users/user/.rbenv/versions/2.3.4/lib/ruby/gems/2.3.0/gems/pry-0.10.4/lib/pry/pry_instance.rb:241:in `catch' 
14: /Users/user/.rbenv/versions/2.3.4/lib/ruby/gems/2.3.0/gems/pry-0.10.4/lib/pry/pry_instance.rb:241:in `eval' 
15: /Users/user/.rbenv/versions/2.3.4/lib/ruby/gems/2.3.0/gems/pry-0.10.4/lib/pry/repl.rb:77:in `block in repl' 
16: /Users/user/.rbenv/versions/2.3.4/lib/ruby/gems/2.3.0/gems/pry-0.10.4/lib/pry/repl.rb:67:in `loop' 
17: /Users/user/.rbenv/versions/2.3.4/lib/ruby/gems/2.3.0/gems/pry-0.10.4/lib/pry/repl.rb:67:in `repl' 
18: /Users/user/.rbenv/versions/2.3.4/lib/ruby/gems/2.3.0/gems/pry-0.10.4/lib/pry/repl.rb:38:in `block in start' 
19: /Users/user/.rbenv/versions/2.3.4/lib/ruby/gems/2.3.0/gems/pry-0.10.4/lib/pry/input_lock.rb:61:in `__with_ownership' 
20: /Users/user/.rbenv/versions/2.3.4/lib/ruby/gems/2.3.0/gems/pry-0.10.4/lib/pry/input_lock.rb:79:in `with_ownership' 
21: /Users/user/.rbenv/versions/2.3.4/lib/ruby/gems/2.3.0/gems/pry-0.10.4/lib/pry/repl.rb:38:in `start' 
22: /Users/user/.rbenv/versions/2.3.4/lib/ruby/gems/2.3.0/gems/pry-0.10.4/lib/pry/repl.rb:15:in `start' 
23: /Users/user/.rbenv/versions/2.3.4/lib/ruby/gems/2.3.0/gems/pry-0.10.4/lib/pry/pry_class.rb:169:in `start' 
24: /Users/user/.rbenv/versions/2.3.4/lib/ruby/gems/2.3.0/gems/pry-byebug-3.4.2/lib/pry-byebug/pry_ext.rb:11:in `start_with_pry_byebug' 
25: /Users/user/.rbenv/versions/2.3.4/lib/ruby/gems/2.3.0/gems/pry-0.10.4/lib/pry/cli.rb:219:in `block in <top (required)>' 
26: /Users/user/.rbenv/versions/2.3.4/lib/ruby/gems/2.3.0/gems/pry-0.10.4/lib/pry/cli.rb:83:in `block in parse_options' 
27: /Users/user/.rbenv/versions/2.3.4/lib/ruby/gems/2.3.0/gems/pry-0.10.4/lib/pry/cli.rb:83:in `each' 
28: /Users/user/.rbenv/versions/2.3.4/lib/ruby/gems/2.3.0/gems/pry-0.10.4/lib/pry/cli.rb:83:in `parse_options' 
29: /Users/user/.rbenv/versions/2.3.4/lib/ruby/gems/2.3.0/gems/pry-0.10.4/bin/pry:16:in `<top (required)>' 
30: /Users/user/.rbenv/versions/2.3.4/bin/pry:22:in `load' 
31: /Users/user/.rbenv/versions/2.3.4/bin/pry:22:in `<main>' 
[7] pry(main)> Rack::Session.method(:constants).source_location 
=> nil 
[8] pry(main)> Rack::Session.method(:const_get).source_location 
=> nil 
[9] pry(main)> Rack::Session.method(:const_missing).source_location 
=> nil 
[10] pry(main)> Rack::Session.method(:const_defined?).source_location 
=> nil 
+0

我找到了答案:如果一個類的主體調用'autoload:ConstantName,'some/file'',那個常量顯示爲被定義,即使它不是。多刺激。 –

回答

0

如果一個類的身體確實這樣:

class Foo 
    autoload :ConstantName, 'some/file' 
end 

...那不斷顯示爲被定義,儘管事實並非如此。這是評估一個常量的行爲的一種方式,可能會有副作用,比如打印到終端上的東西,打開的網絡連接,以及任何你可以想象到的東西放在源文件的主體中。

Foo::ConstantName # Possibly opens your web browser 
        # and points it to something vulgar. 
        # Then installs a rootkit.