MacOSX 上的 Ruby / IRB 环境问题

发布于 2024-10-13 15:17:32 字数 502 浏览 5 评论 0原文

我有一个 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 之后(这也失败了)它似乎有效。

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

I have a ruby script that is failing due to my environment, I think it is demonstrated by this strange behaviour in irb ( I am also using rvm but don't think that is the problem)

>> 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" 

The FileUtils command initially fails but then after typing Help (which also fails) it seems to work.

I have tried require 'rubygems' and require 'FileUtils' - which does fix the problem - but would like to understand whats happening here.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

千寻… 2024-10-20 15:17:32

我不知道有一个“帮助”命令,但显然它依赖于 FileUtils,可能是为了加载帮助文件。 “help”正在将其要求加载到 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% 相信这一点。

I didn't know there was a "help" command, but apparently it has dependency on FileUtils, probably to load help files. "help" is loading its requirements into the IRB session.

>> 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]

It loads the classes in after - before. Where is FileUtils you say? I think its a module that is part of Dir, but I am not 100% on that.

天荒地未老 2024-10-20 15:17:32

您需要 require 'fileutils'

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

默认情况下解释器不包含它,这就是 IRB 不预加载它的原因。由于 IRB 是交互式的,因此它必须即时执行一些解释器不会执行的操作,例如加载帮助文件。它这样做是为了响应您的请求,这对我来说并不意外,这只是它被编程要做的事情。我确信如果您查看其代码,您将能够轻松地追踪它。

所以,基本上,您所看到的只是 IRB 正确响应您的语法错误,然后执行它被告知执行的操作以响应您的“帮助”命令。

如果您绝对必须知道它在做什么,您可以通过要求 IRB 跟踪其处理来弄清楚:

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

输入“help”时将生成 IRB 所做操作的跟踪。搜索该文件显示:

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

当 IRB 加载“ri”时,store.rb 需要该文件。

FileUtils 是 Ruby 标准库的一部分,因此它与解释器捆绑在一起,但不会像 Dir 和 File 一样在解释器启动时自动包含在内。它是完全独立的,不是 Dir 的一部分。

You need to require 'fileutils':

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

It is not included by the interpreter by default, which is why IRB doesn't preload it. Because IRB is interactive, it has to do some things on-the-fly that the interpreter will not, such as load help files. That it does so in response to your request isn't anything unexpected to me, it's just what it was programmed to do. I'm sure if you looked at its code you'd be able to trace it easily enough.

So, basically, all you are seeing is IRB respond correctly to your syntax error, then do what it was told to do in response to your "help" command.

If you absolutely have to know what it's doing, you can figure it out by asking IRB to trace its processing:

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

will generate a tracing of what IRB does when "help" is entered. Searching through the file shows:

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

being required by store.rb as IRB loads 'ri'.

FileUtils is part of the Ruby standard library, so it is bundled with the interpreter, but not included automatically when the interpreter starts, like Dir and File. It is completely standalone, not a part of Dir.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文