2011-01-23 52 views
2

我有一個ruby腳本,由於我的環境而失敗,我認爲這是在irb中這種奇怪的行爲(我也使用rvm,但不認爲這是問題)MacOSX上的Ruby/IRB環境問題

>> ruby -v 
ruby 1.8.7 (2009-06-12 patchlevel 174) [i686-darwin9.8.0] 
>> irb 
>> FileUtils.mkdir_p('tmp') 
    NameError: uninitialized constant FileUtils 
     from (irb):1 
>> help 
    => nil 
>> FileUtils.mkdir_p('tmp') 
    => "tmp" 

FileUtils命令最初失敗,但輸入幫助(也失敗)後,它似乎工作。

我試過要求'rubygems'並且需要'FileUtils' - 它確實解決了這個問題 - 但是想知道這裏發生了什麼。

+1

我想,這很明顯,`help`正在調用`require'fileutils'`的某個地方。你可能會在這裏發現一些關於這方面的內容:https://github.com/ruby/ruby/tree/trunk/lib/irb – zengr 2011-01-23 22:47:08

回答

1

我不知道有一個「幫助」命令,但顯然它依賴於FileUtils,可能會加載幫助文件。 「幫助」正在將其要求加載到IRB會話中。

>> before = ObjectSpace.each_object.map { |i| i.class }.uniq 
=> [Regexp, String, Array, Class, Hash, Module, Proc, MatchData, File, Binding, NoMemoryError, Float, SystemStackError, fatal, Bignum, Object, IO, Thread, ThreadGroup, IRB::Locale, IRB::Notifier::LeveledNotifier, IRB::Notifier::CompositeNotifier, IRB::StdioOutputMethod, IRB::Notifier::NoMsgNotifier, Enumerable::Enumerator, RubyToken::TkNL, RubyToken::TkEND, RubyToken::TkBITOR, RubyToken::TkIDENTIFIER, RubyToken::TkDOT, RubyToken::TkRBRACE, RubyToken::TkSPACE, RubyToken::TkfLBRACE, RubyToken::TkCONSTANT, RubyToken::TkASSIGN, IRB::SLex::Node, IRB::SLex, RubyLex, IRB::ReadlineInputMethod, IRB::WorkSpace, IRB::Context, IRB::Irb] 
>> help 
=> nil 
>> after = ObjectSpace.each_object.map { |i| i.class }.uniq 
=> [Regexp, String, MatchData, Array, Class, RI::ClassEntry, RI::MethodEntry, Hash, Module, Dir, Proc, File, Binding, NoMemoryError, Float, SystemStackError, fatal, Bignum, Object, IO, Thread, ThreadGroup, IRB::Locale, Range, IRB::Notifier::LeveledNotifier, IRB::Notifier::CompositeNotifier, IRB::StdioOutputMethod, IRB::Notifier::NoMsgNotifier, YAML::Syck::Resolver, Gem::ConfigFile, RubyToken::TkNL, RubyToken::TkIDENTIFIER, IRB::SLex::Node, IRB::SLex, RubyLex, IRB::ReadlineInputMethod, IRB::WorkSpace, IRB::Context, IRB::Irb, RI::TopLevelEntry, RI::RiReader, GetoptLong, RI::RiCache, RI::Options, RiDriver, Rational, Date::Infinity, Enumerable::Enumerator, RubyToken::TkRBRACE, DefaultDisplay, RI::TextFormatter] 
>> after == before 
=> false 
>> after - before 
=> [RI::ClassEntry, RI::MethodEntry, Dir, Range, YAML::Syck::Resolver, Gem::ConfigFile, RI::TopLevelEntry, RI::RiReader, GetoptLong, RI::RiCache, RI::Options, RiDriver, Rational, Date::Infinity, DefaultDisplay, RI::TextFormatter] 

它加載after - before中的類。你說FileUtils在哪裏?我認爲它的模塊是Dir的一部分,但我不是100%。

+0

正如錫文說的那樣,OP需要`require'fileutils`` – 2011-01-24 06:35:45

+0

@Ryan Bigg,問題是「爲什麼有助於解決問題」,他表示他在這篇文章的最後一行有這個解決方案。 – EnabrenTane 2011-01-25 06:11:41

1

您需要require 'fileutils'

require 'fileutils' 
FileUtils.pwd # => "/" 

它不是由默認的解釋,這就是爲什麼IRB不預裝它包括在內。由於IRB是交互式的,因此它必須在解釋器不能動的時候做一些事情,比如加載幫助文件。它根據你的要求這樣做對我而言並不是什麼讓人意想不到的,它就是它被編程的目的。我相信如果你看看它的代碼,你就可以很容易地找到它。

因此,基本上,您所看到的只是IRB對您的語法錯誤作出正確迴應,然後根據您的「幫助」命令執行所要求的操作。

如果你絕對要知道它在做什麼,你可以問IRB跟蹤其處理弄明白:

echo help | irb -f --trace > irb.out 

將產生當進入「幫助」 IRB做什麼追查。通過文件搜索顯示:

#0:/Users/greg/.rvm/rubies/ruby-1.9.2-p136/lib/ruby/1.9.1/rdoc/ri/store.rb:2::-: require 'fileutils' 

store.rb要求作爲IRB加載「ri」。

FileUtils是Ruby標準庫的一部分,因此它與解釋器捆綁在一起,但在解釋器啓動時不會自動包含,如Dir和File。它是完全獨立的,不是Dir的一部分。