我有一个由于我的环境而失败的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' - 这确实解决了问题 - 但是想了解这里发生了什么。
答案 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的一部分。