MacOSX上的Ruby / IRB环境问题

时间:2011-01-23 21:34:42

标签: ruby irb

我有一个由于我的环境而失败的ruby脚本,我认为这是由irb中的这种奇怪的行为证明的(我也使用rvm但不认为这是问题)

>> 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命令最初失败,但在键入Help(也失败)后,它似乎工作。

我尝试过'rubygems'并要求'FileUtils' - 这确实解决了问题 - 但是想了解这里发生了什么。

2 个答案:

答案 0 :(得分: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的一部分模块,但我不是百分之百。

答案 1 :(得分: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的一部分。