Saturday, February 27, 2010

E03 in Master

So, I thought porting my E03 script to run on the current Rakudo master would make a good topic for a post. So, what did I have to change?

1. The code wouldn't parse with the metaoperators in it. So they had to go. Sob!

2. Symbol '$is_active_bit' not predeclared. Okay, replace constant with my.

3. No applicable candidates found to dispatch to for 'subst'. Well, that never actually worked properly in alpha, either. Easy enough to replace this with map and a new sub.

4. Method 'e' not found for invocant of class 'Str'. Ack. I just commented out these calls (I presumed :s wouldn't work either).

5. := binding of variables not yet implemented. Switching this to = --- errr --- breaks the code. Guess I'll have to fix that in a minute.

6. Method 'count' not found for invocant of class 'Perl6MultiSub'. Blast. This was triggered by my new code
reduce(&infix:<+>)
. Easy enough to change it to reduce({ $^a + $^b }).

7. Cannot reduce() empty list. Arrrgh! Turns out duplicating what [+] does is harder than it looks. I added a sub sum to cleanly check for the empty list.

8. Nominal type check failed for parameter '@a'; expected Positional but got GatherIterator instead. Oh, no. This is some sort of internal issue showing through, and I have no idea how to fix it.

Guess I will stop there for now, because I don't know how to go further.

sub add_trailing_slash_if_needed($path) {
$path ~~ / \/ $ / ?? $path !! $path ~ '/';
}

sub load_data($filename, $version = 1, *@dirpath is copy) {
@dirpath = './', 'peter' unless +@dirpath;
@dirpath .= map({ add_trailing_slash_if_needed($_) });
say @dirpath.join("\n");

my %data;
for @dirpath -> $prefix {
my $filepath = $prefix ~ $filename;

# if ($filepath ~~ :e and 100 < ($filepath ~~ :s) <= 1e6)
{
say "Trying to open $filepath";
my $fh = open($filepath, :r)
or die "Something screwy with $filepath: $!";
my ($name, $vers, $status, $costs) = $fh.lines(4);
next if $vers < $version;
$costs = [split /\s+/, $costs];
%data{$filepath} = {};
%data{$filepath}<name vers stat costs rest> =
($name, $vers, $status, $costs, $fh.slurp);
say "$filepath done";
$fh.close;
}
}
return %data;
}

sub save_data(%data) {
for %data.kv -> $filepath, $data {
say "saving $filepath";
my $fh = open($filepath, :w)
or die "Something screwy with $filepath: $!";
$fh.print: ($data.<name vers stat>, ~($data.<costs>), $data.<rest>).join("\n");
$fh.close;
}
}

# I've no idea what this sub was supposed to do, so let's stick with something really
# simple for the moment.
sub amortize($a) {
$a;
}

sub sum(@a) {
+@a ?? @a.reduce({ $^a + $^b }) !! 0;
}

my %data = load_data(filename=>'weblog', version=>1);
my $is_active_bit = 0x0080;
for %data.kv -> $file, $data {
say "$file contains data on { $data<name> }";
$data<stat> +^= $is_active_bit;

# my @costs := $data<costs>;
my @costs = $data<costs>;
my $inflation = 0;
$inflation = prompt 'Inflation rate: '
until $inflation > 0;

# @costs = (@costs >>*>> $inflation).sort({ amortize($_) });
@costs = @costs.map({ $_ * $inflation }).sort({ amortize($_) });

# say "Total expenditure: { [+] @costs }";
# say "Major expenditure: { [+] @costs.grep({$_ >= 1000}) }";
# say "Minor expenditure: { [+] @costs.grep({$_ < 1000}) }";

say "Total expenditure: { sum(@costs) }";
say "Major expenditure: { sum(@costs.grep({$_ >= 1000})) }";
say "Minor expenditure: { sum (@costs.grep({$_ < 1000})) }";
say "Odd expenditures: { @costs.map(-> $a, $b { $a }) }";
}

# save_data(%data, log => {name=>'metalog', vers=>1, costs=>[], stat=>0});
save_data(%data);


Update: Adding the words "Perl 6" in text so Ironman picks it up. Sigh.

No comments:

Post a Comment