Skip to content

Instantly share code, notes, and snippets.

@FCO
Last active July 18, 2018 18:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save FCO/5e4dffcc2f47d4c1c2c4a0a4ce74e2c2 to your computer and use it in GitHub Desktop.
Save FCO/5e4dffcc2f47d4c1c2c4a0a4ce74e2c2 to your computer and use it in GitHub Desktop.
#use MONKEY-TYPING;
class TakeIgnoreIterator does Iterator {
has Seq $.original-seq;
has Iterator $!original;
has Iterator $.handling;
has Iterator $!not-handled;
has $.condition = {True};
has Bool $.taking = False;
method pull-one {
my $response;
with $!original-seq {
$!original = $!original-seq.iterator;
$!original-seq = Nil
}
with $!original {
if $!original !~~ ::?CLASS {
$!handling = $!original;
$!original = Nil
} else {
$response := .pull-one;
if $response =:= IterationEnd {
with $!original.not-handled {
$!handling = $_
}
}
}
}
with $!handling {
$response := .pull-one;
if $!taking {
unless $response !=:= IterationEnd and $response ~~ $!condition {
$!not-handled = $!handling;
$!handling = Nil;
$response := IterationEnd
}
} else {
until $response =:= IterationEnd {
last unless $response ~~ $!condition;
$response := .pull-one;
}
$!not-handled = $!handling;
$!handling = Nil;
$response := IterationEnd
}
}
return $response
}
method not-handled {
with $!not-handled {
my $nh = $!not-handled;
$!not-handled = Nil;
return $nh
}
}
}
role TakeIgnoreSeq[$parent = Nil] {
has Seq $.ignored = $parent;
method take-while($condition, Seq :$ignored) {
return .take-while: $condition with $!ignored;
Seq.new(TakeIgnoreIterator.new: :original-seq(self), :$condition, :taking) but TakeIgnoreSeq[$ignored];
}
method take-until($condition, Seq :$ignored) {
return .take-until: $condition with $!ignored;
Seq.new(TakeIgnoreIterator.new: :original-seq(self), :condition{ $_ !~~ $condition }, :taking) but TakeIgnoreSeq[$ignored];
}
method ignore-while($condition) {
my $ignored = Seq.new(TakeIgnoreIterator.new: :original-seq(self), :$condition, :!taking) but TakeIgnoreSeq;
$ignored.take-while(True, :$ignored)
}
method ignore-until($condition) {
my $ignored = Seq.new(TakeIgnoreIterator.new: :original-seq(self), :condition{ $_ !~~ $condition }, :!taking) but TakeIgnoreSeq;
$ignored.take-while(True, :$ignored)
}
}
#augment class Seq { method TWEAK (|) { self does TakeIgnoreSeq } }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment