Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: rubinius/rubinius
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 1111b9483b23^
Choose a base ref
...
head repository: rubinius/rubinius
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: d26443a4086c
Choose a head ref
  • 2 commits
  • 3 files changed
  • 1 contributor

Commits on Apr 30, 2016

  1. Copy the full SHA
    1111b94 View commit details
  2. Copy the full SHA
    d26443a View commit details
Showing with 45 additions and 4 deletions.
  1. +23 −4 machine/instructions.def
  2. +14 −0 spec/ruby/language/fixtures/super.rb
  3. +8 −0 spec/ruby/language/super_spec.rb
27 changes: 23 additions & 4 deletions machine/instructions.def
Original file line number Diff line number Diff line change
@@ -1944,16 +1944,33 @@ instruction zsuper(literal) [ block -- value ]
}

Tuple* tup = Tuple::create(state, arg_count);
for(int i = 0; i < mc->total_args; i++) {
tup->put(state, i, scope->get_local(state, i));
native_int tup_index = 0;

native_int fixed_args;
if(splat) {
fixed_args = mc->splat_position;
} else if(mc->keywords) {
fixed_args = mc->total_args - 1;
} else {
fixed_args = mc->total_args;
}
for(native_int i = 0; i < fixed_args; i++) {
tup->put(state, tup_index++, scope->get_local(state, i));
}

if(splat) {
for(native_int i = 0; i < splat->size(); i++) {
tup->put(state, i + mc->total_args, splat->get(state, i));
tup->put(state, tup_index++, splat->get(state, i));
}
} else if(splat_obj) {
tup->put(state, mc->total_args, splat_obj);
tup->put(state, tup_index++, splat_obj);
}

if(mc->post_args) {
native_int post_position = mc->splat_position + 1;
for(native_int i = post_position; i < post_position + mc->post_args; i++) {
tup->put(state, tup_index++, scope->get_local(state, i));
}
}

if(mc->keywords) {
@@ -1969,6 +1986,8 @@ instruction zsuper(literal) [ block -- value ]

placeholder->send(state, state->symbol("[]="), ary);
}

tup->put(state, tup_index++, scope->get_local(state, placeholder_position));
}

CallSite* call_site = reinterpret_cast<CallSite*>(literal);
14 changes: 14 additions & 0 deletions spec/ruby/language/fixtures/super.rb
Original file line number Diff line number Diff line change
@@ -347,4 +347,18 @@ def foo(a:, b: 'b', **)
end
end
end

module SplatAndKeyword
class A
def foo(*args, **options)
[args, options]
end
end

class B < A
def foo(*args, **options)
super
end
end
end
end
8 changes: 8 additions & 0 deletions spec/ruby/language/super_spec.rb
Original file line number Diff line number Diff line change
@@ -177,5 +177,13 @@ def a(arg)

b.foo.should == {}
end

describe 'when using splat arguments' do
it 'passes splat arguments and keyword arguments to the parent' do
b = Super::SplatAndKeyword::B.new

b.foo('bar', baz: true).should == [['bar'], {baz: true}]
end
end
end
end