I am trying to generate FASTQ files containing 10 random sequences with random quality scores. I originally used the following code, which worked fine:
my @seq = (rand_fa_seq() for ^10);
my @qual = (rand_qual() for ^10);
@seq.perl.say;
@qual.perl.say;
sub rand_fa_seq
{
return join("", roll(20,"ACGT".comb));
}
sub rand_qual
{
return join("", roll(20,"EFGHIJ".comb))
}
However, wanting to simplify it even more, I thought that perhaps I could remove the parentheses from around the right hand statement. When I did so, I only got a single element in @seq
and @qual
.
my @seq = rand_fa_seq() for ^10;
my @qual = rand_qual() for ^10;
@seq.perl.say;
@qual.perl.say;
sub rand_fa_seq
{
return join("", roll(20,"ACGT".comb));
}
sub rand_qual
{
return join("", roll(20,"EFGHIJ".comb))
}
Is this a bug or is this the way it should behave? Without the parentheses is this a scalar context? Will the Great List Refactor change this behavior?
Versions of Perl 6 interpreters in which I have seen this behavior:
MoarVM:
perl6 version 2015.03-204-g8578022 built on MoarVM version 2015.03-60-g36d56f7
JVM:
perl6 version 2015.03-305-ga95107d built on JVM java version "1.7.0_79"
OpenJDK Runtime Environment (rhel-2.5.5.1.el7_1-x86_64 u79-b14)
OpenJDK 64-Bit Server VM (build 24.79-b02, mixed mode)
Statement modifiers are one of the hallmarks of Perl syntax (cf Perl 5's perldoc), and they survived the transition to version 6.
This means your statements are equivalent to
my @seq;
for ^10 { @seq = rand_fa_seq() }
my @qual;
for ^10 { @qual = rand_qual() }
ie you're assigning a fresh value 10 times in a row (and only the last one survives).
Note that this could also be written more succintly as
my @seq = rand_fa_seq() xx 10;
my @qual = rand_qual() xx 10;
Also note that by default, the last statement in a sub provides the return value.
Assuming you might need sequences of length other than 20, you could parametrize that value, ending up with the following:
sub rand-fa-seq($n = 20) { <A C G T>.roll($n).join }
sub rand-qual($n = 20) { <E F G H I J>.roll($n).join }
my @seq = rand-fa-seq() xx 10;
my @qual = rand-qual() xx 10;
where I've used quote words instead of splitting a string.
The second example is like the classical perl5 control statements at the end of the line.
Like
say "true" if something();
say "yeah" for ^10;
if you would put a print statement within rand_qual()
you would notice that it's still being executed 10 times.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With