On 10/5/06, Pit Capitain <pit / capitain.de> wrote: > Tom Allison schrieb: > >>> hostname = open("|hostname").gets > > > > What's with the pipe being at the wrong end? > > What's the thinking behind that? > > You can find a short description in ri or the Pickaxe: > > C:\tmp>ri IO > -------------------------------------------------------------- Class: IO > Class +IO+ is the basis for all input and output in Ruby. An I/O > stream may be _duplexed_ (that is, bidirectional), and so may use > more than one native operating system stream. > > Many of the examples in this section use class +File+, the only > standard subclass of +IO+. The two classes are closely associated. > > As used in this section, _portname_ may take any of the following > forms. > > * A plain string represents a filename suitable for the > underlying operating system. > > >>>>> > * A string starting with ``+|+'' indicates a subprocess. The > remainder of the string following the ``+|+'' is invoked as a > process with appropriate input/output channels connected to it. > >>>>> > > * A string equal to ``+|-+'' will create another Ruby instance as > a subprocess. Just a word of caution about using Kernel#open rather than File#open Kernel#open interprets a path starting with "|" as a pipe, and effectively calls IO#popen under the covers, while File#open doesn't. Kernel open looks like another borrowing from perl, whose standard open function acts this way. Although Ruby has borrowed a lot of good things from perl, I'm not sure that this is one of them. This is dangerous if the path argument is coming from a user, say in a web application, because it opens a security exposure. There have been several exploits of web applications written in perl which take advantage of perl's open function. Awstats is a popular application for showing web server statistics which is written in perl. It's had several nasty security bugs because it wasn't verifying urls and the nasties were doing things which exploited that like getting it to 'pipe' to wget to download worms. When I first came across Ruby's File#open I was happy to see that IT just treats the name argument as a file path, and chokes if it starts with a "|". I think that it's generally better practice in ruby to eschew Kernel#open and use either File#open to open files, and IO#popen to open pipes so that it's clear what's happening. While the Kernel#open method might be convenient and safe in controlled cases, it seems like it might be the basis of a bad habit when it matters. -- Rick DeNatale My blog on Ruby http://talklikeaduck.denhaven2.com/