Skip to content

Commit

Permalink
Merge pull request #2208 from herwinw/kernel_loop
Browse files Browse the repository at this point in the history
  • Loading branch information
seven1m authored Jul 14, 2024
2 parents 4b0463b + 6df84ea commit 76140f2
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 18 deletions.
20 changes: 7 additions & 13 deletions spec/core/kernel/loop_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,22 +42,18 @@
end

it "rescues StopIteration" do
NATFIXME 'it rescues StopIteration', exception: StopIteration do
loop do
raise StopIteration
end
42.should == 42
loop do
raise StopIteration
end
42.should == 42
end

it "rescues StopIteration's subclasses" do
finish = Class.new StopIteration
NATFIXME "it rescues StopIteration's subclasses", exception: finish do
loop do
raise finish
end
42.should == 42
loop do
raise finish
end
42.should == 42
end

it "does not rescue other errors" do
Expand All @@ -70,9 +66,7 @@
y << 2
:stopped
}
NATFIXME 'it returns StopIteration#result, the result value of a finished iterator', exception: StopIteration do
loop { e.next }.should == :stopped
end
loop { e.next }.should == :stopped
end

describe "when no block is given" do
Expand Down
4 changes: 2 additions & 2 deletions src/enumerator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -433,15 +433,15 @@ def with_index(offset = 0, &block)
def uniq(&block)
enum_block = ->(yielder) do
visited = {}
loop do
element = self.next
each do |element|
visiting = block ? block.call(element) : element

yielder.yield(*element) unless visited.include?(visiting)

# We just care about the keys
visited[visiting] = 0
end
visited.clear
end

lazy = Lazy.new(self) {}
Expand Down
16 changes: 13 additions & 3 deletions src/kernel_module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -471,10 +471,20 @@ Value KernelModule::loop(Env *env, Block *block) {
return send(env, "enum_for"_s, { "loop"_s }, size_block);
}

for (;;) {
NAT_RUN_BLOCK_AND_POSSIBLY_BREAK(env, block, {}, nullptr);
try {
for (;;) {
NAT_RUN_BLOCK_AND_POSSIBLY_BREAK(env, block, {}, nullptr);
}
return NilObject::the();
} catch (ExceptionObject *exception) {
auto StopIteration = find_top_level_const(env, "StopIteration"_s);
if (exception->is_a(env, StopIteration)) {
GlobalEnv::the()->set_rescued(true);
return exception->send(env, "result"_s);
} else {
throw exception;
}
}
return NilObject::the();
}

Value KernelModule::method(Env *env, Value name) {
Expand Down

0 comments on commit 76140f2

Please sign in to comment.