Initial implementation of "substr-fields"
This file contains 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 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.