Created
February 24, 2015 13:01
-
-
Save lizmat/c54a35f3002ff0eee070 to your computer and use it in GitHub Desktop.
Initial implementation of "substr-fields"
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Proof-of-concept: | |
The substr-fields() sub creates fields in a string, and allows indexed access to those fields, increasing / shrinking the fields as appropriate if they're changed. | |
The first parameter is the string on which to operate. | |
THe other parameters are from/chars pairs, just like you would use them in a substr(). In this implementation, there are no checks on validity of parameters passed: they must all be in ascending order and not overlap. | |
Comments welcome! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
sub substr-fields(\what, *@fields) { | |
role SubstrFields { | |
has Mu $!parts; | |
has int $!elems; | |
method substrfields-init(@fields) { | |
my Mu $str := nqp::getattr_s(self,Str,'$!value'); | |
$!parts := nqp::list(); | |
my int $start; | |
for @fields -> int $from, int $chars { | |
nqp::push($!parts, | |
nqp::substr($str, $start, nqp::sub_i($from,$start)) | |
); | |
nqp::push($!parts, | |
nqp::substr($str, $from, $chars) | |
); | |
$start = $from + $chars; | |
$!elems = $!elems + 1; | |
} | |
nqp::push($!parts,nqp::substr($str,$start)); | |
} | |
method !update() { | |
nqp::bindattr_s(self,Str,'$!value',nqp::join('',$!parts)); | |
} | |
method at_pos(\pos) { | |
nqp::p6box_s(nqp::atpos($!parts,nqp::unbox_i(pos + pos + 1))); | |
} | |
method assign_pos(\pos,\what) { | |
my str $str = nqp::unbox_s(what); | |
nqp::bindpos($!parts,nqp::unbox_i(pos+pos+1),nqp::unbox_s(what)); | |
self!update; | |
what; | |
} | |
method keys() { @(0..^$!elems) } | |
method list() { self.keys.map: { self.at_pos($_) } } | |
method elems() { nqp::p6box_i($!elems) } | |
method end() { nqp::p6box_i(nqp::sub_i($!elems,1)) } | |
method STORE(*@_) { | |
say "in STORE with @_[]"; | |
} | |
} | |
die "Already has a fields spec" if nqp::istype(what,SubstrFields); | |
what = what but SubstrFields; | |
what.substrfields-init(@fields); | |
what; | |
} | |
my $s = "fXXXooYYYbaz"; | |
substr-fields($s, 1,3, 6,3); # match the XXX and YYY for visual convenience | |
say $s[0]; # XXX | |
say $s.elems; # 2 | |
say $s.keys; # 0 1 | |
say $s.list; # XXX YYY | |
say $s[*]; # XXX YYY | |
say $s[]; # XXX YYY | |
$s[0] = "ZZZZZZZ"; | |
say $s; # fZZZZZZZooYYYbaz | |
#$s[0,1] = <CCCC DDDD>; # work in progress, problem with STORE | |
#say $s; # fCCCCooDDDDbaz |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Wouldn't it make more sense to expose a type for this (for users to use explicitly), rather than hide it all inside a sub?
Maybe the planned Cat type could even handle this?
Also, letting the sub mutate the first argument feels strange, as that's not how the other substr* (and similar built-ins) work.