Combined from primary sources listed below.
See primary docmentation in context for method push.
method push(*@)
Warns the user that they tried to push onto a Nil or derived type object.
See primary docmentation in context for method push.
multi method push(Any:U \SELF: |values --> Positional:D)
The method push is defined for undefined invocants and allows for autovivifying undefined to an empty Array, unless the undefined value implements Positional already. The argument provided will then be pushed into the newly created Array.
my %h;
say %h<a>; # OUTPUT: «(Any)» <-- Undefined
%h<a>.push(1); # .push on Any
say %h; # OUTPUT: «{a => [1]}» <-- Note the Array
See primary docmentation in context for method push.
method push-at-least(Iterator:D: $target, int $count --> Mu)
Should produce at least $count elements, and for each of them, call $target.push($value).
If fewer than $count elements are available from the iterator, it should return the sentinel value IterationEnd. Otherwise it should return $count.
Iterators with side effects should produce exactly $count elements; iterators without side effects (such as Range iterators) can produce more elements to achieve better performance.
my @array;
say (1 .. ∞).iterator.push-at-least(@array, 10); # OUTPUT: «10»
say @array; # OUTPUT: «[1 2 3 4 5 6 7 8 9 10]»
The Iterator role implements this method in terms of pull-one. In general, it is also not intended to be called directly as in the example above. It can be implemented, if unhappy with this default implementation, by those using this role. See the documentation for push-exactly for an example implementation.
See primary docmentation in context for method push.
method push-until-lazy(Iterator:D: $target --> Mu)
Should produce values until it considers itself to be lazy, and push them onto $target.
The Iterator role implements this method as a no-op if is-lazy returns a True value, or as a synonym of push-all if not.
This matters mostly for iterators that have other iterators embedded, some of which might be lazy, while others aren't.
See primary docmentation in context for method push.
method push-all(Iterator:D: $target)
Should produce all elements from the iterator and push them to $target.
my @array;
say (1 .. 1000).iterator.push-all(@array); # All 1000 values are pushed
The Iterator role implements this method in terms of push-at-least. As in the case of the other push-* methods, it is mainly intended for developers implementing this role. push-all is called when assigning an object with this role to an array, for instance, like in this example:
class DNA does Iterable does Iterator {
has $.chain;
has Int $!index = 0;
method new ($chain where {
$chain ~~ /^^ <[ACGT]>+ $$ / and
$chain.chars %% 3 } ) {
self.bless( :$chain );
}
method iterator( ){ self }
method pull-one( --> Mu){
if $!index < $.chain.chars {
my $codon = $.chain.comb.rotor(3)[$!index div 3];
$!index += 3;
return $codon;
} else {
return IterationEnd;
}
}
method push-all(Iterator:D: $target) {
for $.chain.comb.rotor(3) -> $codon {
$target.push: $codon;
}
}
};
my $b := DNA.new("AAGCCT");
my @dna-array = $b;
say @dna-array; # OUTPUT: «[(A A G) (C C T)]»
The push-all method implemented pushes to the target iterator in lists of three amino acid representations; this is called under the covers when we assign $b to @dna-array.
See primary docmentation in context for method push.
method push-exactly(Iterator:D: $target, int $count --> Mu)
Should produce $count elements, and for each of them, call $target.push($value).
If fewer than $count elements are available from the iterator, it should return the sentinel value IterationEnd. Otherwise it should return $count.
my @array;
say (1 .. ∞).iterator.push-exactly(@array, 3); # OUTPUT: «3»
say @array; # OUTPUT: «[1 2 3]»
The Iterator role implements this method in terms of pull-one. In general, this is a method that is not intended to be called directly from the end user who, instead, should implement it in classes that mix the iterator role. For instance, this class implements that role:
class DNA does Iterable does Iterator {
has $.chain;
has Int $!index = 0;
method new ($chain where {
$chain ~~ /^^ <[ACGT]>+ $$ / and
$chain.chars %% 3 } ) {
self.bless( :$chain );
}
method iterator( ){ self }
method pull-one( --> Mu){
if $!index < $.chain.chars {
my $codon = $.chain.comb.rotor(3)[$!index div 3];
$!index += 3;
return $codon;
} else {
return IterationEnd;
}
}
method push-exactly(Iterator:D: $target, int $count --> Mu) {
return IterationEnd if $.chain.elems / 3 < $count;
for ^($count) {
$target.push: $.chain.comb.rotor(3)[ $_ ];
}
}
};
my $b := DNA.new("AAGCCT");
for $b -> $a, $b, $c { say "Never mind" }; # Does not enter the loop
my $þor := DNA.new("CAGCGGAAGCCT");
for $þor -> $first, $second {
say "Coupled codons: $first, $second";
# OUTPUT: «Coupled codons: C A G, C G GCoupled codons: A A G, C C T»
}
This code, which groups DNA chains in triplets (usually called codons) returns those codons when requested in a loop; if too many are requested, like in the first case for $b -> $a, $b, $c, it simply does not enter the loop since push-exactly will return IterationEnd since it is not able to serve the request for exactly 3 codons. In the second case, however, it requests exactly two codons in each iteration of the loop; push-exactly is being called with the number of loop variables as the $count variable.
See primary docmentation in context for method push.
method push(Hash:D: +new)
Adds the new elements to the hash with the same semantics as hash assignment, but with three exceptions:
If a key already exists in the hash, and the corresponding value is an Array, the new value is pushed onto the array (instead of replacing it).
If a key already exists in the hash, and the corresponding value is not an Array, old and new value are both placed into an array in the place of the old value.
Example:
my %h = a => 1;
%h.push: (a => 1); # a => [1,1]
%h.push: (a => 1) xx 3 ; # a => [1,1,1,1,1]
%h.push: (b => 3); # a => [1,1,1,1,1], b => 3
%h.push('c' => 4); # a => [1,1,1,1,1], b => 3, c => 4
push %h, 'd' => 5; # a => [1,1,1,1,1], b => 3, c => 4, d => 5
Please note that literal pairs in the argument list may be interpreted as named arguments and as such won't end up in the Hash:
my %h .= push(e => 6);
say %h.raku; # OUTPUT: «{}»
Use the corresponding subroutine to catch this kind of mistake:
push my %h, f => 7;
CATCH { default { put .message } };
# OUTPUT: «Unexpected named argument 'f' passed»
Also note that push can be used as a replacement for assignment during hash initialization very useful ways. Take for instance the case of an inverted index:
my %wc = 'hash' => 323, 'pair' => 322, 'pipe' => 323;
(my %inv).push: %wc.invert;
say %inv; # OUTPUT: «{322 => pair, 323 => [pipe hash]}»
Note that such an initialization could also be written as
my %wc = 'hash' => 323, 'pair' => 322, 'pipe' => 323;
my %inv .= push: %wc.invert;
Note: Compared to append, push will add the given value as is, whereas append will slip it in:
my %ha = :a[42, ]; %ha.push: "a" => <a b c a>;
say %ha; # OUTPUT: «{a => [42 (a b c a)]}»
my %hb = :a[42, ]; %hb.append: "a" => <a b c a>;
say %hb; # OUTPUT: «{a => [42 a b c a]}»
See primary docmentation in context for sub push.
multi push(\a, **@b is raw)
multi push(\a, \b)
Calls method push on the first argument, passing the remaining arguments. Method push is supposed to add the provided values to the end of the collection or parts thereof. See the documentation of the Hash method for an example where indirection via this subroutine can be helpful.
The push method is supposed to flatten all arguments of type Slip. Therefore, if you want to implement a conforming method for a new collection type, it should behave as if its signature was just:
multi method push(::?CLASS:D: **@values is raw --> ::?CLASS:D)
Autovivification to an instance of the new type is provided by the default base class if the new type implements the Positional role. If the new type is not Positional, autovivification can be supported by adding a multi method with a signature like
multi method push(::?CLASS:U: **@values is raw --> ::?CLASS:D)
See primary docmentation in context for method push.
method push( $elems )
Adds elements at the end of the buffer.
my $bú = Buf.new( 1, 1, 2, 3, 5 );
$bú.push( 8 );
say $bú.raku; # OUTPUT: «Buf.new(1,1,2,3,5,8)»
See primary docmentation in context for method push.
multi method push(Array:D: **@values is raw --> Array:D)
multi method push(Array:D: \value --> Array:D)
multi method push(Array:D: Slip \values --> Array:D)
Adds the provided value or values to the end of the array, and returns the modified array. If any argument is a Slip, method push will add the values produced by the argument's iterator. It throws if the invocant array or a Slip is lazy.
Example:
my @foo = <a b c>;
@foo.push: 'd';
say @foo; # OUTPUT: «[a b c d]»
Note that push does not attempt to flatten its argument list. If you pass an array or list as the thing to push, it becomes one additional element:
my @a = <a b c>;
my @b = <d e f>;
@a.push: @b;
say @a.elems; # OUTPUT: «4»
say @a[3].join; # OUTPUT: «def»
Multiple values are added to the array only if you supply them as separate arguments or in a Slip:
my @a = '1';
say @a.push: 'a', 'b'; # OUTPUT: «[1 a b]»
my @c = <E F>;
say @a.push: @c.Slip; # OUTPUT: «[1 a b E F]»
See method append if you want to append multiple values that are produced by a single non-slipping Iterable.
See primary docmentation in context for method push.
method push(IterationBuffer:D: Mu \value)
Adds the given value at the end of the IterationBuffer and returns the given value.