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
7 changes: 0 additions & 7 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,6 @@ Note: We're only listing outstanding class updates.

* `Array#rfind` has been added as a more efficient alternative to `array.reverse_each.find` [[Feature #21678]]
* `Array#find` has been added as a more efficient override of `Enumerable#find` [[Feature #21678]]
* `Array#pack` accepts a new format `R` and `r` for unpacking unsigned
and signed LEB128 encoded integers. [[Feature #21785]]

* Binding

* `Binding#local_variables` does no longer include numbered parameters.
Expand Down Expand Up @@ -267,9 +264,6 @@ Note: We're only listing outstanding class updates.
* `String#strip`, `strip!`, `lstrip`, `lstrip!`, `rstrip`, and `rstrip!`
are extended to accept `*selectors` arguments. [[Feature #21552]]

* `String#unpack` accepts a new format `R` and `r` for unpacking unsigned
and signed LEB128 encoded integers. [[Feature #21785]]

* Thread

* Introduce support for `Thread#raise(cause:)` argument similar to
Expand Down Expand Up @@ -575,5 +569,4 @@ A lot of work has gone into making Ractors more stable, performant, and usable.
[Feature #21678]: https://bugs.ruby-lang.org/issues/21678
[Bug #21698]: https://bugs.ruby-lang.org/issues/21698
[Feature #21701]: https://bugs.ruby-lang.org/issues/21701
[Feature #21785]: https://bugs.ruby-lang.org/issues/21785
[Bug #21789]: https://bugs.ruby-lang.org/issues/21789
12 changes: 4 additions & 8 deletions array.c
Original file line number Diff line number Diff line change
Expand Up @@ -2102,9 +2102,7 @@ rb_ary_fetch(int argc, VALUE *argv, VALUE ary)
*
* If no such element is found, calls +if_none_proc+ and returns its return value.
*
* [1, 3, 5].find(proc {false}) {|element| element > 12} # => false
* [[:foo, 0], [:bar, 1], [:baz, 2]].find {|key, value| key.start_with?('b') } # => [:bar, 1]
* [[:foo, 0], [:bar, 1], [:baz, 2]].find(proc {[]}) {|key, value| key.start_with?('c') } # => []
* [1, 3, 5].find(proc {-1}) {|element| element > 12} # => -1
*
* With no block given, returns an Enumerator.
*
Expand Down Expand Up @@ -2140,16 +2138,14 @@ rb_ary_find(int argc, VALUE *argv, VALUE ary)
* Returns the last element for which the block returns a truthy value.
*
* With a block given, calls the block with successive elements of the array in
* reverse order; returns the last element for which the block returns a truthy
* reverse order; returns the first element for which the block returns a truthy
* value:
*
* (0..9).rfind {|element| element < 5} # => 4
* [1, 2, 3, 4, 5, 6].rfind {|element| element < 5} # => 4
*
* If no such element is found, calls +if_none_proc+ and returns its return value.
*
* (0..9).rfind(proc {false}) {|element| element < -2} # => false
* {foo: 0, bar: 1, baz: 2}.rfind {|key, value| key.start_with?('b') } # => [:baz, 2]
* {foo: 0, bar: 1, baz: 2}.rfind(proc {[]}) {|key, value| key.start_with?('c') } # => []
* [1, 2, 3, 4].rfind(proc {0}) {|element| element < -2} # => 0
*
* With no block given, returns an Enumerator.
*
Expand Down
37 changes: 23 additions & 14 deletions cont.c
Original file line number Diff line number Diff line change
Expand Up @@ -3246,28 +3246,37 @@ rb_fiber_raise(VALUE fiber, int argc, VALUE *argv)

/*
* call-seq:
* fiber.raise -> obj
* fiber.raise(string) -> obj
* fiber.raise(exception [, string [, array]]) -> obj
* raise(exception, message = exception.to_s, backtrace = nil, cause: $!)
* raise(message = nil, cause: $!)
*
* Raises an exception in the fiber at the point at which the last
* +Fiber.yield+ was called. If the fiber has not been started or has
* +Fiber.yield+ was called.
*
* f = Fiber.new {
* puts "Before the yield"
* Fiber.yield 1 # -- exception will be raised here
* puts "After the yield"
* }
*
* p f.resume
* f.raise "Gotcha"
*
* Output
*
* Before the first yield
* 1
* t.rb:8:in 'Fiber.yield': Gotcha (RuntimeError)
* from t.rb:8:in 'block in <main>'
*
* If the fiber has not been started or has
* already run to completion, raises +FiberError+. If the fiber is
* yielding, it is resumed. If it is transferring, it is transferred into.
* But if it is resuming, raises +FiberError+.
*
* With no arguments, raises a +RuntimeError+. With a single +String+
* argument, raises a +RuntimeError+ with the string as a message. Otherwise,
* the first parameter should be the name of an +Exception+ class (or an
* object that returns an +Exception+ object when sent an +exception+
* message). The optional second parameter sets the message associated with
* the exception, and the third parameter is an array of callback information.
* Exceptions are caught by the +rescue+ clause of <code>begin...end</code>
* blocks.
*
* Raises +FiberError+ if called on a Fiber belonging to another +Thread+.
*
* See Kernel#raise for more information.
* See Kernel#raise for more information on arguments.
*
*/
static VALUE
rb_fiber_m_raise(int argc, VALUE *argv, VALUE self)
Expand Down
6 changes: 3 additions & 3 deletions doc/language/box.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Ruby Box is designed to provide separated spaces in a Ruby process, to isolate a

## TODOs

* Add the loaded namespace on iseq to check if another namespace tries running the iseq (add a field only when VM_CHECK_MODE?)
* Add the loaded box on iseq to check if another box tries running the iseq (add a field only when VM_CHECK_MODE?)
* Assign its own TOPLEVEL_BINDING in boxes
* Fix calling `warn` in boxes to refer `$VERBOSE` and `Warning.warn` in the box
* Make an internal data container class `Ruby::Box::Entry` invisible
Expand All @@ -22,7 +22,7 @@ Ruby Box is designed to provide separated spaces in a Ruby process, to isolate a
### Enabling Ruby Box

First, an environment variable should be set at the ruby process bootup: `RUBY_BOX=1`.
The only valid value is `1` to enable namespace. Other values (or unset `RUBY_BOX`) means disabling namespace. And setting the value after Ruby program starts doesn't work.
The only valid value is `1` to enable Ruby Box. Other values (or unset `RUBY_BOX`) means disabling Ruby Box. And setting the value after Ruby program starts doesn't work.

### Using Ruby Box

Expand Down Expand Up @@ -75,7 +75,7 @@ There are two box types:

There is the root box, just a single box in a Ruby process. Ruby bootstrap runs in the root box, and all builtin classes/modules are defined in the root box. (See "Builtin classes and modules".)

User boxes are to run user-written programs and libraries loaded from user programs. The user's main program (specified by the `ruby` command line argument) is executed in the "main" box, which is a user namespace automatically created at the end of Ruby's bootstrap, copied from the root box.
User boxes are to run user-written programs and libraries loaded from user programs. The user's main program (specified by the `ruby` command line argument) is executed in the "main" box, which is a user box automatically created at the end of Ruby's bootstrap, copied from the root box.

When `Ruby::Box.new` is called, an "optional" box (a user, non-main box) is created, copied from the root box. All user boxes are flat, copied from the root box.

Expand Down
4 changes: 4 additions & 0 deletions doc/language/character_selectors.rdoc
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ Each of these instance methods accepts one or more character selectors:
- String#delete!(*selectors): returns +self+ or +nil+.
- String#squeeze(*selectors): returns a new string.
- String#squeeze!(*selectors): returns +self+ or +nil+.
- String#strip(*selectors): returns a new string.
- String#strip!(*selectors): returns +self+ or +nil+.

A character selector identifies zero or more characters in +self+
that are to be operands for the method.
Expand Down Expand Up @@ -79,6 +81,8 @@ These instance methods accept multiple character selectors:
- String#delete!(*selectors): returns +self+ or +nil+.
- String#squeeze(*selectors): returns a new string.
- String#squeeze!(*selectors): returns +self+ or +nil+.
- String#strip(*selectors): returns a new string.
- String#strip!(*selectors): returns +self+ or +nil+.

In effect, the given selectors are formed into a single selector
consisting of only those characters common to _all_ of the given selectors.
Expand Down
2 changes: 0 additions & 2 deletions doc/language/packed_data.rdoc
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,6 @@ These tables summarize the directives for packing and unpacking.

U | UTF-8 character
w | BER-compressed integer
R | LEB128 encoded unsigned integer
r | LEB128 encoded signed integer

=== For Floats

Expand Down
5 changes: 2 additions & 3 deletions doc/syntax/calling_methods.rdoc
Original file line number Diff line number Diff line change
Expand Up @@ -355,9 +355,8 @@ as one argument:
# Prints the object itself:
# #<Name:0x00007f9d07bca650 @name="Jane Doe">

This allows to handle one or many arguments polymorphically. Note also that +nil+
has NilClass#to_a defined to return an empty array, so conditional unpacking is
possible:
This allows to handle one or many arguments polymorphically. Note also that <tt>*nil</tt>
is unpacked to an empty list of arguments, so conditional unpacking is possible:

my_method(*(some_arguments if some_condition?))

Expand Down
24 changes: 24 additions & 0 deletions enumerator.c
Original file line number Diff line number Diff line change
Expand Up @@ -1230,6 +1230,24 @@ enumerator_inspect(VALUE obj)
* (1..100).to_a.permutation(4).size # => 94109400
* loop.size # => Float::INFINITY
* (1..100).drop_while.size # => nil
*
* Note that enumerator size might be inaccurate, and should be rather treated as a hint.
* For example, there is no check that the size provided to ::new is accurate:
*
* e = Enumerator.new(5) { |y| 2.times { y << it} }
* e.size # => 5
* e.to_a.size # => 2
*
* Another example is an enumerator created by ::produce without a +size+ argument.
* Such enumerators return +Infinity+ for size, but this is inaccurate if the passed
* block raises StopIteration:
*
* e = Enumerator.produce(1) { it + 1 }
* e.size # => Infinity
*
* e = Enumerator.produce(1) { it > 3 ? raise(StopIteration) : it + 1 }
* e.size # => Infinity
* e.to_a.size # => 4
*/

static VALUE
Expand Down Expand Up @@ -3051,6 +3069,12 @@ producer_size(VALUE obj, VALUE args, VALUE eobj)
* File.dirname(it)
* }
* traverser.size # => 4
*
* # Finite enumerator with unknown size
* calendar = Enumerator.produce(Date.today, size: nil) {
* it.monday? ? raise(StopIteration) : it + 1
* }
* calendar.size # => nil
*/
static VALUE
enumerator_s_produce(int argc, VALUE *argv, VALUE klass)
Expand Down
3 changes: 3 additions & 0 deletions eval.c
Original file line number Diff line number Diff line change
Expand Up @@ -922,6 +922,9 @@ rb_f_raise(int argc, VALUE *argv)
* With argument +exception+ not given,
* argument +message+ and keyword argument +cause+ may be given,
* but argument +backtrace+ may not be given.
*
* +cause+ can not be given as an only argument.
*
*/

static VALUE
Expand Down
83 changes: 0 additions & 83 deletions pack.c
Original file line number Diff line number Diff line change
Expand Up @@ -667,56 +667,6 @@ pack_pack(rb_execution_context_t *ec, VALUE ary, VALUE fmt, VALUE buffer)
}
break;

case 'r': /* r for SLEB128 encoding (signed) */
case 'R': /* R for ULEB128 encoding (unsigned) */
{
int pack_flags = INTEGER_PACK_LITTLE_ENDIAN;

if (type == 'r') {
pack_flags |= INTEGER_PACK_2COMP;
}

while (len-- > 0) {
size_t numbytes;
int sign;
char *cp;

from = NEXTFROM;
from = rb_to_int(from);
numbytes = rb_absint_numwords(from, 7, NULL);
if (numbytes == 0)
numbytes = 1;
VALUE buf = rb_str_new(NULL, numbytes);

sign = rb_integer_pack(from, RSTRING_PTR(buf), RSTRING_LEN(buf), 1, 1, pack_flags);

if (sign < 0 && type == 'R') {
rb_raise(rb_eArgError, "can't encode negative numbers in ULEB128");
}

if (type == 'r') {
/* Check if we need an extra byte for sign extension */
unsigned char last_byte = (unsigned char)RSTRING_PTR(buf)[numbytes - 1];
if ((sign >= 0 && (last_byte & 0x40)) || /* positive but sign bit set */
(sign < 0 && !(last_byte & 0x40))) { /* negative but sign bit clear */
/* Need an extra byte */
rb_str_resize(buf, numbytes + 1);
RSTRING_PTR(buf)[numbytes] = sign < 0 ? 0x7f : 0x00;
numbytes++;
}
}

cp = RSTRING_PTR(buf);
while (1 < numbytes) {
*cp |= 0x80;
cp++;
numbytes--;
}

rb_str_buf_cat(res, RSTRING_PTR(buf), RSTRING_LEN(buf));
}
}
break;
case 'u': /* uuencoded string */
case 'm': /* base64 encoded string */
from = NEXTFROM;
Expand Down Expand Up @@ -1608,39 +1558,6 @@ pack_unpack_internal(VALUE str, VALUE fmt, enum unpack_mode mode, long offset)
}
break;

case 'r':
case 'R':
{
int pack_flags = INTEGER_PACK_LITTLE_ENDIAN;

if (type == 'r') {
pack_flags |= INTEGER_PACK_2COMP;
}
char *s0 = s;
while (len > 0 && s < send) {
if (*s & 0x80) {
s++;
}
else {
s++;
UNPACK_PUSH(rb_integer_unpack(s0, s-s0, 1, 1, pack_flags));
len--;
s0 = s;
}
}
/* Handle incomplete value and remaining expected values with nil (only if not using *) */
if (!star) {
if (s0 != s && len > 0) {
UNPACK_PUSH(Qnil);
len--;
}
while (len-- > 0) {
UNPACK_PUSH(Qnil);
}
}
}
break;

case 'w':
{
char *s0 = s;
Expand Down
14 changes: 14 additions & 0 deletions range.c
Original file line number Diff line number Diff line change
Expand Up @@ -1018,6 +1018,20 @@ range_to_a(VALUE range)
return rb_call_super(0, 0);
}

/*
* call-seq:
* to_set -> set
*
* Returns a set containing the elements in +self+, if a finite collection;
* raises an exception otherwise.
*
* (1..4).to_set # => Set[1, 2, 3, 4]
* (1...4).to_set # => Set[1, 2, 3]
*
* (1..).to_set
* # in 'Range#to_set': cannot convert endless range to a set (RangeError)
*
*/
static VALUE
range_to_set(int argc, VALUE *argv, VALUE range)
{
Expand Down
23 changes: 0 additions & 23 deletions spec/ruby/core/array/pack/r_spec.rb

This file was deleted.

4 changes: 2 additions & 2 deletions spec/ruby/core/array/pack/shared/basic.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
# NOTE: it's just a plan of the Ruby core team
it "warns that a directive is unknown" do
# additional directive ('a') is required for the X directive
-> { [@obj, @obj].pack("a K" + pack_format) }.should complain(/unknown pack directive 'K'/)
-> { [@obj, @obj].pack("a R" + pack_format) }.should complain(/unknown pack directive 'R'/)
-> { [@obj, @obj].pack("a 0" + pack_format) }.should complain(/unknown pack directive '0'/)
-> { [@obj, @obj].pack("a :" + pack_format) }.should complain(/unknown pack directive ':'/)
end
Expand All @@ -48,7 +48,7 @@
# NOTE: Added this case just to not forget about the decision in the ticket
it "raise ArgumentError when a directive is unknown" do
# additional directive ('a') is required for the X directive
-> { [@obj, @obj].pack("a K" + pack_format) }.should raise_error(ArgumentError, /unknown pack directive 'K'/)
-> { [@obj, @obj].pack("a R" + pack_format) }.should raise_error(ArgumentError, /unknown pack directive 'R'/)
-> { [@obj, @obj].pack("a 0" + pack_format) }.should raise_error(ArgumentError, /unknown pack directive '0'/)
-> { [@obj, @obj].pack("a :" + pack_format) }.should raise_error(ArgumentError, /unknown pack directive ':'/)
end
Expand Down
2 changes: 1 addition & 1 deletion spec/ruby/core/string/unpack/shared/basic.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
ruby_version_is "3.3" do
# https://bugs.ruby-lang.org/issues/19150
it 'raise ArgumentError when a directive is unknown' do
-> { "abcdefgh".unpack("a K" + unpack_format) }.should raise_error(ArgumentError, /unknown unpack directive 'K'/)
-> { "abcdefgh".unpack("a R" + unpack_format) }.should raise_error(ArgumentError, /unknown unpack directive 'R'/)
-> { "abcdefgh".unpack("a 0" + unpack_format) }.should raise_error(ArgumentError, /unknown unpack directive '0'/)
-> { "abcdefgh".unpack("a :" + unpack_format) }.should raise_error(ArgumentError, /unknown unpack directive ':'/)
end
Expand Down
Loading