ROOM FOR IMPROVEMENT: It would probably be better if the class defined below implemented the Buf "role". That way, code that used it could (for example) call .list and .elems directly on the class... which I think would be a very nice way to open up the class. Or is that TOO open? Meh, I think people who hack on Commodore 1541 diskette images should be implicitly trusted.
class Image {
has Str $.sourcefile is rw; # accessors auto-generated
has Buf $!buffer; # private, no accessors
has $!hdr = (17 * 21) * 256; # byte offset
method load() {
return "no sourcefile specified" unless $.sourcefile;
# read in a binary file
my $fh = open( $.sourcefile, :r, :bin );
$!buffer = $fh.slurp-rest(:bin);
return "$.sourcefile loaded";
# (oops - forgot to close the file)
}
method size() { $!buffer.elems }
# Each of these methods return "Buf": a class used
# for dealing with binary data buffers.
method label() { $!buffer.subbuf($!hdr + 143, 16) }
method hdr() { $!buffer.subbuf($!hdr, 256) }
method dir( Int $index ) {
my $offset = $!hdr + 256 + $index * 32;
return $!buffer.subbuf($offset+2, 30);
}
}
my Image $test = Image.new( sourcefile => "mule.d64" );
say $test.load();
say $test.size(), " bytes read";
my $hdr = $test.hdr();
my $label = $test.label();
print "Label: ";
for $label.list -> $val {
if 31 < $val < 92 { print chr($val) }
else { print '.' }
}
print "\n";
my $blob = $test.dir(1); # (actually the 2nd entry)
for $blob.list -> $val {
if 31 < $val < 92 { print chr($val) }
else { print '.' }
}
% perl6 Image.p6
mule.d64 loaded
174848 bytes read
Label: .M.U.L.E........
...MULE.2.....................
Thursday, February 11, 2016
Friday, February 5, 2016
Perl6: January installer for Windows
http://rakudo.org/downloads/star/
Finally, a new .msi for Perl6.
Finally, a new .msi for Perl6.
Wednesday, February 3, 2016
Perl6: insane (in a good way)
Just an example. I can't believe how amusing yet efficient this syntax is.
my %ingredients = :4eggs, :2sticks-of-butter, :4cups-of-sugar;
say %ingredients;
# OUTPUT>>:
# cups-of-sugar => 4, eggs => 4, sticks-of-butter => 2
Is Perl6 really Perl?
There has been some discussion about whether Perl6 was mis-named.
I thought that that was a silly discussion not worth getting involved in. It's quite obviously Perl in some form.
The argument, if I understand it, is that Perl6 "sounds like" a version increment from Perl 5. This violates the principle of least surprise.
OK, I can understand that. In that sense it would be mis-named. But then what do you CALL it? I haven't seen any suggestions.
So I'll suggest one based on the compiler used for it. Call it Rakudo. At least until a better name is thunk up.
I thought that that was a silly discussion not worth getting involved in. It's quite obviously Perl in some form.
The argument, if I understand it, is that Perl6 "sounds like" a version increment from Perl 5. This violates the principle of least surprise.
OK, I can understand that. In that sense it would be mis-named. But then what do you CALL it? I haven't seen any suggestions.
So I'll suggest one based on the compiler used for it. Call it Rakudo. At least until a better name is thunk up.
Monday, February 1, 2016
Perl6: error by design in split()?
So while splitting a string, I found some odd results. But it's actually NOT a bug... and therefore I consider that to be a DESIGN ERROR.
Suppose we have a $string "Hello, world!", and we split it into characters. In Perl, we do it these ways:
my @foo = split '', $string; # perl 5
my @foo = $string.split(''); # perl 6
And in both cases, we end up with an array:
[ H e l l o , w o r l d ! ]
HOWEVER, in Perl6 I see something odd: two extra characters in my stream:
[] <= what's that? \0? \b?
[H]
[e]
[l]
[l]
[o]
[,]
[ ]
[w]
[o]
[r]
[l]
[d]
[!]
[] <= what's that? \0? \b?
So let's check to see if those two end elements are defined.
for @bar -> $letter
{
printf "[$letter] %x\n", $letter.ord if $letter;
say "undef" unless $letter;
}
undef
[H] 48
[e] 65
[l] 6c
[l] 6c
[o] 6f
[,] 2c
[ ] 20
[w] 77
[o] 6f
[r] 72
[l] 6c
[d] 64
[!] 21
undef
Looks like a bug to me. And yet the docs say:
If
A number of optional named parameters can be specified, which alter the result being returned. The
Baloney. That's not how I expect split to work BY DEFAULT. I expect that string to be split, and nothing added, thank you very much.
EVEN BETTER, :skip-empty doesn't appear to work in the admittedly pre-1.0 version of Perl6 I'm running (2015.09).
Suppose we have a $string "Hello, world!", and we split it into characters. In Perl, we do it these ways:
my @foo = split '', $string; # perl 5
my @foo = $string.split(''); # perl 6
And in both cases, we end up with an array:
[ H e l l o , w o r l d ! ]
HOWEVER, in Perl6 I see something odd: two extra characters in my stream:
[] <= what's that? \0? \b?
[H]
[e]
[l]
[l]
[o]
[,]
[ ]
[w]
[o]
[r]
[l]
[d]
[!]
[] <= what's that? \0? \b?
So let's check to see if those two end elements are defined.
for @bar -> $letter
{
printf "[$letter] %x\n", $letter.ord if $letter;
say "undef" unless $letter;
}
undef
[H] 48
[e] 65
[l] 6c
[l] 6c
[o] 6f
[,] 2c
[ ] 20
[w] 77
[o] 6f
[r] 72
[l] 6c
[d] 64
[!] 21
undef
Looks like a bug to me. And yet the docs say:
If
DELIMITER is a string, it is searched for literally and not treated as a regex. If DELIMITER
is the empty string, it effectively returns all characters of the
string separately (plus an empty string at the begin and at the end).A number of optional named parameters can be specified, which alter the result being returned. The
:v, :k, :kv and :p named parameters all perform a special action with regards to the delimiter found.- :skip-empty
Baloney. That's not how I expect split to work BY DEFAULT. I expect that string to be split, and nothing added, thank you very much.
EVEN BETTER, :skip-empty doesn't appear to work in the admittedly pre-1.0 version of Perl6 I'm running (2015.09).
Friday, January 29, 2016
A Short Perl6 ASCII Rotator
This script rotates a simple chunk of ASCII art based on user input (90, 180, or 270 degrees). It's not very elegant, and there's a minor and annoying bug in it, but I'm done for the day, so. Here's a test run:
+OO
OOO
OOO
% 90
OOO
OOO
+OO
% 180
OO+
OOO
OOO
% 270
OOO
OOO
OO+
% 180
+OO
OOO
OOO
%
And here's the code.
my Str @test = ("+OO"
,"OOO"
,"OOO");
my $r = 0;
loop
{
run( 'cls' );
say @test.join( "\n" );
my $in = prompt "\n% ";
@test = rotate( 90, @test ) if $in ~~ /90/;
@test = rotate( 180, @test ) if $in ~~ /180/;
@test = rotate( 270, @test ) if $in ~~ /270/;
}
sub rotate( $degrees, Str @pixobject )
{
return @pixobject if $degrees % 360 == 0;
my Str @a = @pixobject;
@a = rotate90( @a );
@a = rotate90( @a ) if $degrees > 90;
@a = rotate90( @a ) if $degrees > 180;
return @a;
}
sub rotate90( Str @pixobject )
{
my Str @new = ();
for @pixobject -> $line
{
my Str @row = $line.split('');
my $len = @row.elems;
for (0..$len) -> $i
{
@new[$len-$i] = '' unless @new[$len-$i];
@new[$len-$i] ~= @row[$i] if @row[$i];
}
}
return @new;
}
+OO
OOO
OOO
% 90
OOO
OOO
+OO
% 180
OO+
OOO
OOO
% 270
OOO
OOO
OO+
% 180
+OO
OOO
OOO
%
And here's the code.
my Str @test = ("+OO"
,"OOO"
,"OOO");
my $r = 0;
loop
{
run( 'cls' );
say @test.join( "\n" );
my $in = prompt "\n% ";
@test = rotate( 90, @test ) if $in ~~ /90/;
@test = rotate( 180, @test ) if $in ~~ /180/;
@test = rotate( 270, @test ) if $in ~~ /270/;
}
sub rotate( $degrees, Str @pixobject )
{
return @pixobject if $degrees % 360 == 0;
my Str @a = @pixobject;
@a = rotate90( @a );
@a = rotate90( @a ) if $degrees > 90;
@a = rotate90( @a ) if $degrees > 180;
return @a;
}
sub rotate90( Str @pixobject )
{
my Str @new = ();
for @pixobject -> $line
{
my Str @row = $line.split('');
my $len = @row.elems;
for (0..$len) -> $i
{
@new[$len-$i] = '' unless @new[$len-$i];
@new[$len-$i] ~= @row[$i] if @row[$i];
}
}
return @new;
}
Subscribe to:
Comments (Atom)