Extremely Noobish Documentation Question

Hello all,

I am a Java programmer and am attempting to learn Ruby. What I have
seen so far, I really like. I have been through two of the tutorials
linked to from the main site and read the Poignant Guide to Ruby.
However, when I refer to the actual documentation, I find it lacking ...
or maybe I'm just confused. In many examples I have seen File.open used
but when I refer to the official documentation
(http://www.ruby-doc.org/core/) the 'open' method is not listed for the
File class.

After doing some digging, I think I understand that it is some kind of
alias to 'new' but how would I know that (if I'm even right). Also, I
think File inherits from IO but I can't see in the documentation where
this is indicated. Am I just looking at it all wrong? Am I looking in
the wrong place? Basically, I like the language but the documentation I
have seen appears to be lacking compared to the Java API. Any help
would be greatly appreciated.

Thanks,
Paco

···

--
Posted via http://www.ruby-forum.com/.

Patrick McNally wrote:
In many examples I have seen File.open used

but when I refer to the official documentation
(http://www.ruby-doc.org/core/\) the 'open' method is not listed for the
File class.

Paco

Hi,

open methed is a method defined in kernel module. Open a window prompt
and try the following

C:\>ri open
More than one method matched your request. You can refine
your search by asking for information on one of:

     CSV::open, CSV::open_reader, CSV::open_writer, Dir::open,
     ...
     Iconv::open, IO::open, IO::popen, IO::sysopen, IO#reopen,
     Kernel#open, Kernel#open_uri_original_open,
     ... Win32::EventLog::open_backup

Form the screen you can see kernel#open. This is where open comes from.
BTW Ruby is case sensitive.

After that you can try the follows

C:\>ri Kernel.open
------------------------------------------------------------ Kernel#open
     open(path [, mode [, perm]] ) => io or nil
     open(path [, mode [, perm]] ) {|io| block } => obj

···

------------------------------------------------------------------------
     Creates an +IO+ object connected to the given stream, file, or
     subprocess.

     ....
        open("testfile") do |f|
          print f.gets
        end

     _produces:_

        This is line one

     Open a subprocess and read its output:

        cmd = open("|date")
        print cmd.gets
        cmd.close

     _produces:_

        Wed Apr 9 08:56:31 CDT 2003

-- More --

...

Li

--
Posted via http://www.ruby-forum.com/\.

You did everything well : ruby-doc.org is the place to find the api, and you
should have found exactly what you were looking for (eg. the File.open class
method), in normal time...

But for some reasons, it happens that the generated doc gets bloated by
classes that should not be there, in the core api. Maybe a mistake from
someone, maybe a technical problem, perhaps someone in the ML knows what
happens ?
In any case, this is annoying : in your case, the original File class api was
replaced by another one, which is useless to you.

You can use ri instead, but it's not as simple as ruby-doc. And I don't know
another place to find this api. Another solution is to generate the api
yourself with rdoc.

···

Le dimanche 26 novembre 2006 22:53, Paco Paco a écrit :

...
but when I refer to the official documentation
(http://www.ruby-doc.org/core/\) the 'open' method is not listed for the
File class.
...

Isn't the problem here that the File class inherits from the IO class?
IO has an open method, therefore File has an open method. But you have
to look under IO to see it.

It might be helpful to have on hand a script that reports a class's
methods by cycling up the inheritance chain for you:

def method_report(klass)
  result = klass.ancestors.inject(Array.new) do |result, anc|
    ms = (anc.instance_methods + anc.methods).sort.uniq
    result.last[1] -= ms if result.last
    result << [anc.name, ms]
  end
  result.each do |k, v|
    puts "----", k
    v.each {|m| puts "\s\s#{m}"}
  end
end
# and here's how to use it
method_report(File)

m.

···

Paco Paco <mepaco@gmail.com> wrote:

In many examples I have seen File.open used
but when I refer to the official documentation
(http://www.ruby-doc.org/core/\) the 'open' method is not listed for the
File class.

--
matt neuburg, phd = matt@tidbits.com, Matt Neuburg’s Home Page
Tiger - http://www.takecontrolbooks.com/tiger-customizing.html
AppleScript - http://www.amazon.com/gp/product/0596102119
Read TidBITS! It's free and smart. http://www.tidbits.com

Basically, I like the language but the documentation I
have seen appears to be lacking compared to the Java API. Any help
would be greatly appreciated.

The problem you're trying to solve seems to be the same
I tried to solve with magic/help - documentation is there,
but it's difficult to find the right one.

With magic/help you can do:

help 'File.open'

or even:

help { File.open }

magic/help then uses reflection, Ruby debugging hooks,
and other tricks, so if what you're looking for is there,
magic/help is going to find it for you :wink:

You can find more about magic/help at

Some improvements from magic/help have been incorporated into
recent versions of fastri, so fastri often works when the standard ri wouldn't.

···

On 11/26/06, Paco Paco <mepaco@gmail.com> wrote:

--
Tomasz Wegrzanowski [ http://t-a-w.blogspot.com/ ]

open methed is a method defined in kernel module

Thank you for the quick response. I see that now but I guess my
underlying questions still remains. What should indicate that the
method is part of Kernel and why is it invoked when I call 'File.open'?
I apologize if I am asking these questions in the wrong place. I'm just
feeling a little lost.

If there is a more comprehensive resource that I should read, let me
know. I hate to be asking questions that have answers elsewhere, but
I've found that most of the documentation I have seen does not answer
the questions I have.

-Paco

···

--
Posted via http://www.ruby-forum.com/\.

Or, get fastri:

$ fri File.open
--------------------------------------------------------------- IO::open
      IO.open(fd, mode_string="r" ) => io
      IO.open(fd, mode_string="r" ) {|io| block } => obj

···

On Sun, 26 Nov 2006 23:09:07 -0000, matt neuburg <matt@tidbits.com> wrote:

It might be helpful to have on hand a script that reports a class's
methods by cycling up the inheritance chain for you:

------------------------------------------------------------------------
      With no associated block, open is a synonym for IO::new. If the
      optional code block is given, it will be passed io as an argument,
      and the IO object will automatically be closed when the block
      terminates. In this instance, IO::open returns the value of the
      block.

It handles the inheritance stuff much better than RI.
See http://eigenclass.org/hiki.rb?fastri+0.2.0

--
Ross Bamford - rosco@roscopeco.remove.co.uk

Patrick McNally wrote:

open methed is a method defined in kernel module
    
Thank you for the quick response. I see that now but I guess my underlying questions still remains. What should indicate that the method is part of Kernel and why is it invoked when I call 'File.open'? I apologize if I am asking these questions in the wrong place. I'm just feeling a little lost.

If there is a more comprehensive resource that I should read, let me know. I hate to be asking questions that have answers elsewhere, but I've found that most of the documentation I have seen does not answer the questions I have.

-Paco

Ruby's doc is not as comprehensive as Java's. That's all there is to it. There's also 100 million Java books but only 2 dozen or so for Ruby. You'll catch up as you go along. In addition to ruby-doc, I recommend you get a copy of Dave Thomas' _Programming_Ruby_. If you really get into Ruby there's a couple other good books. Consider Hal Fulton's _The_Ruby_Way_, David Black's _Ruby_for_Rails_, or the _Ruby_Cookbook_ (can't remember the authors' names).

Patrick McNally wrote:

open methed is a method defined in kernel module

Thank you for the quick response. I see that now but I guess my
underlying questions still remains. What should indicate that the
method is part of Kernel and why is it invoked when I call 'File.open'?
I apologize if I am asking these questions in the wrong place. I'm just
feeling a little lost.

If there is a more comprehensive resource that I should read, let me
know. I hate to be asking questions that have answers elsewhere, but
I've found that most of the documentation I have seen does not answer
the questions I have.

-Paco

check this out
http://dev.rubycentral.com/ref/

or Pickaxe 1st edition(online version)
http://www.ruby-doc.org/docs/ProgrammingRuby/

But the better means is to buy a Pickaxe 2nd edition(Dave Thomas'
Programming Ruby) and read it on the bed when you feel there is nothing
else to do.

Li

···

--
Posted via http://www.ruby-forum.com/\.

Patrick McNally wrote:

open methed is a method defined in kernel module

Thank you for the quick response. I see that now but I guess my
underlying questions still remains. What should indicate that the
method is part of Kernel and why is it invoked when I call 'File.open'?

Because the File class inherits all the methods from the Kernel class:

p File.ancestors

[File, IO, File::Constants, Enumerable, Object, Kernel]

Like any other class, File has access to the methods of its ancestors.

···

--
Paul Lutus
http://www.arachnoid.com

Patrick McNally schrieb:

open methed is a method defined in kernel module
    
Thank you for the quick response.

This answer was not correct. You cannot find the File.open method, because there is none. It is inherited from the IO class, because File < IO == true. If you want to find out where a method is located you can type this into irb:
>> File.method(:open)
# => #<Method: File(IO).open>

This shows the inheritance relation. Ruby's rdoc/ri is a bit stupid, and can't locate inherited methods so well.

There is also a Kernel#open method, that is mixed into the Object class as a private method. This makes it possible to open a file by calling
open(filename) do |file|
  #...
end
from everywhere. If you call File.open this isn't the method called, because IO#open is found first:

>> require 'pp'; pp File.ancestors.map { |klass| [ klass, klass.method(:open) ] }
[[File, #<Method: File(IO).open>],
[IO, #<Method: IO.open>],
[File::Constants, #<Method: Module(Kernel)#open>],
[Enumerable, #<Method: Module(Kernel)#open>],
[Object, #<Method: Class(Kernel)#open>],
[PP::ObjectMixin, #<Method: Module(Kernel)#open>],
[Kernel, #<Method: Kernel.open>]]

You can call Kernel#open only without an explicit receiver, because it is private. That's why calling, e. g., Array.open would fail with a NoMethodError.

···

--
Florian Frank

Hi --

open methed is a method defined in kernel module

Thank you for the quick response. I see that now but I guess my
underlying questions still remains. What should indicate that the
method is part of Kernel and why is it invoked when I call 'File.open'?

It isn't; the method that's invoked is IO.open. Here's a (very)
schematic version of what's going on:

   module Kernel
     def open(*args)
       # do one of these:
       IO.open(args)
       # or
       IO.popen(args)
       # depending on presence of pipe character
     end

     private :open
   end

   class IO
     def IO.open(*args)
       io_object = new
       # now do some logic branching, depending on whether
       # or not a code block is present in the method call
       return io_object
     end
   end

   class File < IO
   end

Now, note the following:

Kernel#open is a private instance method of Kernel. That means that
*every* Ruby object can see that method. It also means (for reasons I
won't go into here, but that are in my book :slight_smile: that you can only ever
call it *without* an explicit receiver:

   some_random_object.open(...) # no good: trying to call private
                                  # method "open"
   open(...) # OK, because no receiver present

If IO.open didn't exist, then when you did:

   IO.open(...)

Ruby would think you were trying to call the private Kernel method
"open". But in fact you're not, because there's a new and separate
open method defined as a class method in IO.

Finally, File.open works because, as a subclass of IO, File gets to call
IO's class methods. File.open, like IO.open, is not the same as the
generic, private open method provided by the Kernel module.

You can even show this in action, by overriding Kernel#open. (This
will create a public version of it, so I won't get the error message
about calling a private message.)

   irb(main):001:0> module Kernel; def open; "Hello!"; end; end
   => nil
   irb(main):002:0> 1.open
   => "Hello!"
   irb(main):003:0> "some string".open
   => "Hello!"
   irb(main):004:0> IO.open
   ArgumentError: wrong number of arguments (0 for 1)

Well, I got an error on IO.open, but that shows that the method being
called was IO.open, and not the new version of Kernel#open.

David

···

On Mon, 27 Nov 2006, Patrick McNally wrote:

--
                   David A. Black | dblack@wobblini.net
Author of "Ruby for Rails" [1] | Ruby/Rails training & consultancy [3]
DABlog (DAB's Weblog) [2] | Co-director, Ruby Central, Inc. [4]
[1] Ruby for Rails | [3] http://www.rubypowerandlight.com
[2] http://dablog.rubypal.com | [4] http://www.rubycentral.org

Nevertheless, fastri does not list "open" among File's method's:

matt-neuburgs-imac-g5:~ mattneub$ fri File
------------------------------------------------------------ Class: File
[snip]

···

Ross Bamford <rosco@roscopeco.remove.co.uk> wrote:

On Sun, 26 Nov 2006 23:09:07 -0000, matt neuburg <matt@tidbits.com> wrote:

> It might be helpful to have on hand a script that reports a class's
> methods by cycling up the inheritance chain for you:
>

Or, get fastri:

$ fri File.open
--------------------------------------------------------------- IO::open
      IO.open(fd, mode_string="r" ) => io
      IO.open(fd, mode_string="r" ) {|io| block } => obj

------------------------------------------------------------------------
[snip]
Class methods:
     atime, basename, blockdev?, catname, chardev?, chmod, chmod,
     chown, compare, copy, ctime, delete, directory?, dirname,
     executable?, executable_real?, exist?, exists?, expand_path,
     extname, file?, fnmatch, fnmatch?, ftype, grpowned?, identical?,
     install, join, lchmod, lchown, link, lstat, makedirs, move, mtime,
     new, owned?, pipe?, readable?, readable_real?, readlink, rename,
     safe_unlink, setgid?, setuid?, size, size?, socket?, split, stat,
     sticky?, symlink, symlink?, syscopy, truncate, umask, unlink,
     utime, writable?, writable_real?, zero?

Instance methods:
     atime, chmod, chown, ctime, flock, lstat, mtime, o_chmod, path,
     truncate

That is why I supplied a script that does list it. Perhaps this could be
a reasonable feature request for a future version of fastri. m.

--
matt neuburg, phd = matt@tidbits.com, Matt Neuburg’s Home Page
Tiger - http://www.takecontrolbooks.com/tiger-customizing.html
AppleScript - http://www.amazon.com/gp/product/0596102119
Read TidBITS! It's free and smart. http://www.tidbits.com

Timothy Hunter wrote:

Patrick McNally wrote:

know. I hate to be asking questions that have answers elsewhere, but
I've found that most of the documentation I have seen does not answer
the questions I have.

-Paco

Ruby's doc is not as comprehensive as Java's. That's all there is to it.
There's also 100 million Java books but only 2 dozen or so for Ruby.
You'll catch up as you go along. In addition to ruby-doc, I recommend
you get a copy of Dave Thomas' _Programming_Ruby_. If you really get
into Ruby there's a couple other good books. Consider Hal Fulton's
_The_Ruby_Way_, David Black's _Ruby_for_Rails_, or the _Ruby_Cookbook_
(can't remember the authors' names).

Ruby Cookbook, by Lucas Carlson and Leonard Richardson (O'Reiily).
*Highly* recommended, after you finish Pickaxe II.

···

--
Posted via http://www.ruby-forum.com/\.

Hi --

···

On Mon, 27 Nov 2006, Paul Lutus wrote:

Patrick McNally wrote:

open methed is a method defined in kernel module

Thank you for the quick response. I see that now but I guess my
underlying questions still remains. What should indicate that the
method is part of Kernel and why is it invoked when I call 'File.open'?

Because the File class inherits all the methods from the Kernel class:

p File.ancestors

[File, IO, File::Constants, Enumerable, Object, Kernel]

Like any other class, File has access to the methods of its ancestors.

In this case, though, the open that gets called is the class method
from IO, rather than the instance method from Kernel. All objects
have access to that instance method, but since it's private, it
doesn't usually do them much good.

David

--
                   David A. Black | dblack@wobblini.net
Author of "Ruby for Rails" [1] | Ruby/Rails training & consultancy [3]
DABlog (DAB's Weblog) [2] | Co-director, Ruby Central, Inc. [4]
[1] Ruby for Rails | [3] http://www.rubypowerandlight.com
[2] http://dablog.rubypal.com | [4] http://www.rubycentral.org

Wow! I have to say I'm a little shocked at how many people were so
quick to help. Thank you all. Being a Java developer (therefore
familiar with inheritance) I was going to ask whether it was really
IO.open being used but thought I would read a little more in case I was
missing something.

Thanks for all the reading suggestions too. I'll probably pick up one
or two to read over the Christmas break. Pickaxe II sounds like a
popular choice. I'm a little disappointed in the API documentation
(what is that entry for File that doesn't even show it has a Parent?)
but I'll give fastri a shot. Thanks again for all the help.

-Paco

···

--
Posted via http://www.ruby-forum.com/.