Method: Kernel#open

Defined in:
io.c

#open(path[, mode [, perm]][, opt]) ⇒ IO? #open(path[, mode [, perm]][, opt]) {|io| ... } ⇒ Object

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

If path does not start with a pipe character (|), treat it as the name of a file to open using the specified mode (defaulting to “r”).

The mode is either a string or an integer. If it is an integer, it must be bitwise-or of open(2) flags, such as File::RDWR or File::EXCL. If it is a string, it is either “fmode”, “fmode:ext_enc”, or “fmode:ext_enc:int_enc”.

See the documentation of IO.new for full documentation of the mode string directives.

If a file is being created, its initial permissions may be set using the perm parameter. See File.new and the open(2) and chmod(2) man pages for a description of permissions.

If a block is specified, it will be invoked with the IO object as a parameter, and the IO will be automatically closed when the block terminates. The call returns the value of the block.

If path starts with a pipe character ("|"), a subprocess is created, connected to the caller by a pair of pipes. The returned IO object may be used to write to the standard input and read from the standard output of this subprocess.

If the command following the pipe is a single minus sign ("|-"), Ruby forks, and this subprocess is connected to the parent. If the command is not "-", the subprocess runs the command.

When the subprocess is Ruby (opened via "|-"), the open call returns nil. If a block is associated with the open call, that block will run twice — once in the parent and once in the child.

The block parameter will be an IO object in the parent and nil in the child. The parent’s IO object will be connected to the child’s $stdin and $stdout. The subprocess will be terminated at the end of the block.

Examples

Reading from “testfile”:

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

Open a subprocess running the same Ruby program:

f = open("|-", "w+")
if f.nil?
  puts "in Child"
  exit
else
  puts "Got: #{f.gets}"
end

Produces:

Got: in Child

Open a subprocess using a block to receive the IO object:

open "|-" do |f|
  if f then
    # parent process
    puts "Got: #{f.gets}"
  else
    # child process
    puts "in Child"
  end
end

Produces:

Got: in Child

Overloads:

  • #open(path[, mode [, perm]][, opt]) ⇒ IO?

    Returns:

    • (IO, nil)
  • #open(path[, mode [, perm]][, opt]) {|io| ... } ⇒ Object

    Yields:

    • (io)

    Returns:



7187
7188
7189
7190
7191
7192
7193
7194
7195
7196
7197
7198
7199
7200
7201
7202
7203
7204
7205
7206
7207
7208
7209
7210
7211
7212
7213
7214
7215
7216
7217
7218
7219
7220
7221
7222
# File 'io.c', line 7187

static VALUE
rb_f_open(int argc, VALUE *argv, VALUE _)
{
    ID to_open = 0;
    int redirect = FALSE;

    if (argc >= 1) {
	CONST_ID(to_open, "to_open");
	if (rb_respond_to(argv[0], to_open)) {
	    redirect = TRUE;
	}
	else {
	    VALUE tmp = argv[0];
	    FilePathValue(tmp);
	    if (NIL_P(tmp)) {
		redirect = TRUE;
	    }
	    else {
                VALUE cmd = check_pipe_command(tmp);
                if (!NIL_P(cmd)) {
		    argv[0] = cmd;
		    return rb_io_s_popen(argc, argv, rb_cIO);
		}
	    }
	}
    }
    if (redirect) {
        VALUE io = rb_funcallv_kw(argv[0], to_open, argc-1, argv+1, RB_PASS_CALLED_KEYWORDS);

	if (rb_block_given_p()) {
	    return rb_ensure(rb_yield, io, io_close, io);
	}
	return io;
    }
    return rb_io_s_open(argc, argv, rb_cFile);
}