Reputation: 23
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.
Upvotes: 2
Views: 605
Reputation: 160551
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.
Upvotes: 1
Reputation: 7466
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.
Upvotes: 1