In perl5, what about something like...
my $a = []; $a->[1]{bar}{baz}[3] = 7;
bless $a, "hrmph";
*hrmph::deref = sub { $_[0]->[1]{bar}{baz}[3] };
print "yeah: ", $a->deref, "\n";
It's maybe not the clearest or most maintainable thing in the whole wide world, but it's not "impossible." You could even build on it to make it more readable, reliable, and more flexible in various ways.
(UPDATE: I clicked the wrong reply button, so if there's a kind editor that could move me up a level?)
UPDATE: Oh, I see what you're up to I think. Some function you build once and applicate anwhere. I am also a little surprised your $x->$deref.
| [reply] [d/l] [select] |
In perl5, what about something like...
my $a = []; $a->[1]{bar}{baz}[3] = 7;
bless $a, "hrmph";
*hrmph::deref = sub { $_[0]->[1]{bar}{baz}[3] };
print "yeah: ", $a->deref, "\n";
Well, that's not quite the same thing, because you create a method for each "dereferencing chain". I was talking about putting it e.g. in some scalar or in an aggregate. But now that you got me thinking, this is certainly possible and even easier than what you wrote:
my $x = []; $x->[1]{bar}{baz}[3] = 7;
bless $x, "whatever";
my $deref = sub { $_[0]->[1]{bar}{baz}[3] };
print "yeah: ", $x->$deref, "\n";
What's even more interesting is that the variable appearently doesn't need to be blessed at all, which I wouldn't have known nor suspected without trying. In fact the following works just the same too:
my $x = []; $x->[1]{bar}{baz}[3] = 7;
# bless $x, "whatever";
my $deref = sub { $_[0]->[1]{bar}{baz}[3] };
print "yeah: ", $x->$deref, "\n";
It's maybe not the clearest or most maintainable thing in the whole wide world, but it's not "impossible."
Well, what I wrote -literally- is still impossible: that is precisely to have a "dereferencing chain" as a self sustained "single entity", existing in and of itself without a reference to be applied to. In fact here we have a cheap workaround that is perfectly equivalent. Yet it's not, from the "philosophical" POV, exactly the same thing.
| [reply] [d/l] [select] |
$object->$code(@args);
the corresponding sub is called as a method on $object. This is often used to implement callbacks in a way that personally I like:
$object->record( name => 'doit',
callback => sub {
my $caller=shift;
# ...
} );
| [reply] [d/l] [select] |
If you reverse their order, it's simply a closure:
$dereferencer = { $^moose.<foo>[1]<bar><baz>[3] };
$dereferencer($datastructure);
Yep this is very akin to what Joost suggested for Perl 5 (and was also mentioned in the original thread), except that it's more 6ish. I was thinking... is in general the semantics of $datastructure.$dereferencer definite? Is it valid syntax anyway? If not, could a C<.> infix multi, or even a macro, be specified to "amount to" the function call specified above?
| [reply] [d/l] [select] |
multi sub infix:<at> ($dsc, Code $deref) {
$deref($dsc);
}
my %data = ( foo => [ { quux => 3 }, { bar => { baz => [ 1, 2, 3, 4 ]
+}, }, ], );
my $dereferencer = { .<foo>[1]<bar><baz>[3] };
say %data at $dereferencer;
Works in Pugs. Since there doesn't seem to be any good documentation about macros yet, I don't know how to beautify the dereferencer construction syntax, but it ought to be trivial to make a macro that translates deref <foo><bar><baz>[1] to { .<foo><bar><baz>[1] }.
UPDATE: Fixed some blaring typos in the code. Thanks for noting it, blazar. (For some reason, you can't define a Hash in Pugs with
my Hash %foo = (
# something
);
At least I get a syntax error with Pugs 6.2.13.)
| [reply] [d/l] [select] |
$dereferencer = { .<foo>[1]<bar><baz>[3] };
I knew that "unary" dot acts implicitly on $_, but appearently your code implies that in code written as a bare block $_ is an alias to the first positional argument, and that I didn't know. Actually, without knowing, I would have written the above amongst other possibilities, like:
$dereferencer = -> $d { $d.<foo>[1]<bar><baz>[3] };
| [reply] [d/l] [select] |
Well, like I said in the update: for $datastructure to respond to the $dereferencer method, you need it to do a certain Role. This can be achieved on the fly.
| [reply] [d/l] [select] |