Re: hash copy

2019-03-24 Thread Marcel Timmerman

Hi Brad and Yari,

Thanks very much for your in depth explanations.

Regards,
Marcel


Re: hash copy

2019-03-24 Thread yary
Brad Gilbert wrote:
>Which shows that if you are dealing with a Hash it is probably better
>to use a % variable.

Indeed and coming from Perl 5 I find using the sigils % and @ for "does
Associative" and "does Positional" maps better to that experience.

> my %a = :s1(4.3), :s2(2.1), :s3(5.3);
{s1 => 4.3, s2 => 2.1, s3 => 5.3}
> my %b = %a
{s1 => 4.3, s2 => 2.1, s3 => 5.3}
> %b=1
1
> %a
4.3

-y


On Sun, Mar 24, 2019 at 7:58 AM Brad Gilbert  wrote:

> You created a single Hash then assigned it to two variables.
>
> Also `clone` always does a shallow clone.
> So there will be two Hashes, but the values will still share the same
> scalar container.
> If you add a new key it won't be in the other Hash.
>
> my $a = { a => 1 };
> my $b = $a.clone;
> $b = 2;
>
> say $a; # {a => 1}
> say $b; # {a => 1, b => 2}
>
> $b = 3;
> say $a; # {a => 3}
>
> You could work around that by deleting the key first.
>
> $b:delete;
> $b = 5;
>
> Or by creating the second Hash some other way
>
> my $b = %( $a.pairs );
> my $b = %( $a.kv );
>
> my %b = $a;
>
> Which shows that if you are dealing with a Hash it is probably better
> to use a % variable.
>
> If you want to define the type of Hash-like container you can:
>
> my %b is Hash = $a;
>
> my %b is BagHash = $a;
> my %b is Bag = $a; # immutable
>
> On Sun, Mar 24, 2019 at 6:11 AM Marcel Timmerman  wrote:
> >
> > Hi,
> >
> > I was wandering if the following is an assignment or a binding (or
> binding of the entries);
> >
> > my Hash $sleep-wait = { :s1(4.3), :s2(2.1), :s3(5.3), :s4(10.4),
> :s5(8.7),};
> >
> > my Hash $sleep-left = $sleep-wait;
> >
> >
> >
> > I noticed that in the following piece of code the $sleep-wait hash
> entries were set to 0
> > I had to explicitly do a copy to let it function correctly; 'my Hash
> $sleep-left = %(|$sleep-wait);'
> > Also cloning didn't work.
> >
> > use v6;
> >
> > my Hash $sleep-wait = {
> >
> >   :s1(4.3), :s2(2.1), :s3(5.3), :s4(10.4), :s5(8.7),
> >
> > };
> >
> > my Hash $sleep-left = $sleep-wait;
> >
> > loop {
> >
> >   # get shortest sleep
> >
> >   my $t = 1_000_000.0;
> >
> >   my $s;
> >
> >   for $sleep-left.keys -> $k {
> >
> > if $sleep-left{$k} < $t {
> >
> >   $t = $sleep-left{$k};
> >
> >   $s = $k;
> >
> > }
> >
> >   }
> >
> >   # set back to original time
> >
> >   $sleep-left{$s} = $sleep-wait{$s};
> >
> >   note "Reset entry $s to $sleep-left{$s} (from $sleep-wait{$s})";
> >
> >   # adjust remaining entries
> >
> >   for $sleep-left.keys -> $k {
> >
> > next if $s eq $k;
> >
> > $sleep-left{$k} -= $t;
> >
> > $sleep-left{$k} = $sleep-wait{$k} if $sleep-left{$k} <= 0;
> >
> >   }
> >
> >   note "sleep for $t sec, entry $s";
> >
> >   sleep $t;
> >
> > }
> >
> >
> > perl version;
> >
> > This is Rakudo version 2018.12-363-ga1c2e20d7 built on MoarVM version
> 2018.12-117-gdcafbc4c7
> > implementing Perl 6.d.
> >
> >
> > Regards,
> > Marcel
>


Re: hash copy

2019-03-24 Thread Brad Gilbert
You created a single Hash then assigned it to two variables.

Also `clone` always does a shallow clone.
So there will be two Hashes, but the values will still share the same
scalar container.
If you add a new key it won't be in the other Hash.

my $a = { a => 1 };
my $b = $a.clone;
$b = 2;

say $a; # {a => 1}
say $b; # {a => 1, b => 2}

$b = 3;
say $a; # {a => 3}

You could work around that by deleting the key first.

$b:delete;
$b = 5;

Or by creating the second Hash some other way

my $b = %( $a.pairs );
my $b = %( $a.kv );

my %b = $a;

Which shows that if you are dealing with a Hash it is probably better
to use a % variable.

If you want to define the type of Hash-like container you can:

my %b is Hash = $a;

my %b is BagHash = $a;
my %b is Bag = $a; # immutable

On Sun, Mar 24, 2019 at 6:11 AM Marcel Timmerman  wrote:
>
> Hi,
>
> I was wandering if the following is an assignment or a binding (or binding of 
> the entries);
>
> my Hash $sleep-wait = { :s1(4.3), :s2(2.1), :s3(5.3), :s4(10.4), :s5(8.7),};
>
> my Hash $sleep-left = $sleep-wait;
>
>
>
> I noticed that in the following piece of code the $sleep-wait hash entries 
> were set to 0
> I had to explicitly do a copy to let it function correctly; 'my Hash 
> $sleep-left = %(|$sleep-wait);'
> Also cloning didn't work.
>
> use v6;
>
> my Hash $sleep-wait = {
>
>   :s1(4.3), :s2(2.1), :s3(5.3), :s4(10.4), :s5(8.7),
>
> };
>
> my Hash $sleep-left = $sleep-wait;
>
> loop {
>
>   # get shortest sleep
>
>   my $t = 1_000_000.0;
>
>   my $s;
>
>   for $sleep-left.keys -> $k {
>
> if $sleep-left{$k} < $t {
>
>   $t = $sleep-left{$k};
>
>   $s = $k;
>
> }
>
>   }
>
>   # set back to original time
>
>   $sleep-left{$s} = $sleep-wait{$s};
>
>   note "Reset entry $s to $sleep-left{$s} (from $sleep-wait{$s})";
>
>   # adjust remaining entries
>
>   for $sleep-left.keys -> $k {
>
> next if $s eq $k;
>
> $sleep-left{$k} -= $t;
>
> $sleep-left{$k} = $sleep-wait{$k} if $sleep-left{$k} <= 0;
>
>   }
>
>   note "sleep for $t sec, entry $s";
>
>   sleep $t;
>
> }
>
>
> perl version;
>
> This is Rakudo version 2018.12-363-ga1c2e20d7 built on MoarVM version 
> 2018.12-117-gdcafbc4c7
> implementing Perl 6.d.
>
>
> Regards,
> Marcel