Skip to content

Instantly share code, notes, and snippets.

@lizmat
Created February 24, 2015 13:01
Show Gist options
  • Save lizmat/c54a35f3002ff0eee070 to your computer and use it in GitHub Desktop.
Save lizmat/c54a35f3002ff0eee070 to your computer and use it in GitHub Desktop.
Initial implementation of "substr-fields"
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!
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
@smls
Copy link

smls commented Feb 24, 2015

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment