Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 59 additions & 37 deletions io.c
Original file line number Diff line number Diff line change
Expand Up @@ -8266,33 +8266,47 @@ rb_open_file(VALUE io, VALUE fname, VALUE vmode, VALUE vperm, VALUE opt)
/*
* Document-method: File::open
*
* :markup: markdown
*
* call-seq:
* File.open(path, mode = 'r', perm = 0666, **opts) -> file
* File.open(path, mode = 'r', perm = 0666, **opts) {|f| ... } -> object
* File.open(path, mode = 'r', permissions = 0666, **options) -> file
* File.open(path, mode = 'r', permissions = 0666, **options) {|file| ... } -> object
*
* Creates a new \File object via File.new with the given arguments.
*
* Creates a new File object, via File.new with the given arguments.
* With no block given, returns the \File object.
*
* With no block given, returns the File object.
* With a block given, calls the block with the \File object,
* closes the \File object, and returns the block's value:
*
* With a block given, calls the block with the File object
* and returns the block's value.
* ```ruby
* File.open('doc/maintainers.md') {|file| file.size } # => 14900
* ```
*
* Note that the \File object is automatically closed
* even if the block raises an exception.
*/

/*
* Document-method: IO::open
*
* :markup: markdown
*
* call-seq:
* IO.open(fd, mode = 'r', **opts) -> io
* IO.open(fd, mode = 'r', **opts) {|io| ... } -> object
* IO.open(fd, mode = 'r', **options) -> io
* IO.open(fd, mode = 'r', **options) {|io| ... } -> object
*
* Creates a new \IO object, via IO.new with the given arguments.
* Creates a new \IO object via IO.new with the given arguments.
*
* With no block given, returns the \IO object.
*
* With a block given, calls the block with the \IO object
* and returns the block's value.
* With a block given, calls the block with the \IO object,
* closes the \IO object, and returns the blocks value:
*
* ```ruby
* fd = File.sysopen('doc/maintainers.md') # => 6
* IO.open(fd) {|io| io.read.size } # => 14897
* ```
*/

static VALUE
Expand Down Expand Up @@ -9744,43 +9758,51 @@ rb_io_set_encoding_by_bom(VALUE io)
}

/*
* :markup: markdown
*
* call-seq:
* File.new(path, mode = 'r', perm = 0666, **opts) -> file
* File.new(path, mode = 'r', permissions = 0666, **options) -> file
*
* Opens the file at the given +path+ according to the given +mode+;
* creates and returns a new File object for that file.
* Opens the file as specified by the given arguments.
* Creates and returns a new open \File object for that file;
* the opened file is in non-synchronous mode.
*
* The new File object is buffered mode (or non-sync mode), unless
* +filename+ is a tty.
* See IO#flush, IO#fsync, IO#fdatasync, and IO#sync=.
* Argument `path` must the string path to an existing filesystem entry:
*
* Argument +path+ must be a valid file path:
* ```ruby
* file = File.new('doc/maintainers.md') # => #<File:doc/maintainers.md>
* file.close # Clean up.
* tty = File.new('/dev/tty') # => #<File:/dev/tty>
* tty.close # Clean up.
* ```
*
* f = File.new('/etc/fstab')
* f.close
* f = File.new('t.txt')
* f.close
* Note that the caller is responsible for closing the file;
* see File.open for automatic closing.
*
* Optional argument +mode+ (defaults to 'r') must specify a valid mode;
* see {Access Modes}[rdoc-ref:File@Access+Modes]:
* Optional argument `mode` (defaults to `'r'`) must specify a valid mode;
* see [Access Modes](rdoc-ref:File@Access+Modes):
*
* f = File.new('t.tmp', 'w')
* f.close
* f = File.new('t.tmp', File::RDONLY)
* f.close
* ```ruby
* file = File.new('t.tmp', 'w') # => #<File:t.tmp>
* file.close # Clean up.
* file = File.new('t.tmp', File::RDONLY) # => #<File:t.tmp>
* file.close # Clean up.
* ```
*
* Optional argument +perm+ (defaults to 0666) must specify valid permissions
* see {File Permissions}[rdoc-ref:File@File+Permissions]:
* Optional argument `permissions` (defaults to `0666`) must specify valid permissions;
* see [File Permissions](rdoc-ref:File@File+Permissions):
*
* f = File.new('t.tmp', File::CREAT, 0644)
* f.close
* f = File.new('t.tmp', File::CREAT, 0444)
* f.close
* ```ruby
* file = File.new('t.tmp', 'w', 0644) # => #<File:t.tmp>
* file.close # Clean up.
* file = File.new('t.tmp', 'w', 0444) # => #<File:t.tmp>
* file.close # Clean up.
* ```
*
* Optional keyword arguments +opts+ specify:
* Optional keyword arguments `options` specify:
*
* - {Open Options}[rdoc-ref:IO@Open+Options].
* - {Encoding options}[rdoc-ref:encodings.rdoc@Encoding+Options].
* - [Open Options](rdoc-ref:IO@Open+Options).
* - [Encoding options](rdoc-ref:encodings.rdoc@Encoding+Options).
*
*/

Expand Down
1 change: 1 addition & 0 deletions string.c
Original file line number Diff line number Diff line change
Expand Up @@ -10946,6 +10946,7 @@ rb_str_enumerate_lines(int argc, VALUE *argv, VALUE str, VALUE ary)
line = rb_str_subseq(str, subptr - ptr, subend - subptr);
if (ENUM_ELEM(ary, line)) {
str_mod_check(str, ptr, len);
str_mod_check(rs, rsptr, rslen);
}
subptr = hit;
}
Expand Down
10 changes: 10 additions & 0 deletions test/ruby/test_string.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1619,6 +1619,16 @@ def test_each_line
$VERBOSE = verbose
end

def test_each_line_modified_separator
sep = S("x" * 1_000_000)
res = []
assert_raise_with_message(RuntimeError, /string modified/) do
S("a#{sep}b#{sep}c").each_line(sep) do |x|
sep.clear
end
end
end

def test_each_line_chomp
res = []
S("hello\nworld").each_line("\n", chomp: true) {|x| res << x}
Expand Down