Re: how to self define a operator
by choroba (Cardinal) on Oct 22, 2019 at 06:26 UTC
|
See Sub::Infix for a safe way to define your own operators (but not exactly what you requested).
map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
| [reply] [d/l] |
|
|
Thanks, It is interesting!
| [reply] |
Re: how to self define a operator
by vr (Curate) on Oct 22, 2019 at 10:26 UTC
|
It's not clear how hypothetical operator should behave in case of multi-D slices. Your "reshape" solution simply fills new container with existing data regardless of row/column/plane boundaries, just like pouring liquid from one vessel to another of different shape, under normal gravity, and it's only exact volume that matters. Should 2-D matrix be perhaps transposed? Anyway, existing facilities can solve these tasks without repeating a slice expression twice -- if that's what you want to avoid.
E.g., for "liquid data to fill new vessel", both RHS and LHS piddles can be flattened, and since the latter is virtual, changes will flow to original multi-D piddle:
pdl> p$p = sequence 2,5
[
[0 1]
[2 3]
[4 5]
[6 7]
[8 9]
]
pdl> p$t3 = $t2 = ($t1 = zeroes 4,3) .= -1
[
[-1 -1 -1 -1]
[-1 -1 -1 -1]
[-1 -1 -1 -1]
]
pdl> $t1(0:2,1:2)->(;_) .= $p(0:1,1:3)->(;_); p$t1
[
[-1 -1 -1 -1]
[ 2 3 4 -1]
[ 5 6 7 -1]
]
pdl> $t2(0:2,1:2)->flat .= $p(0:1,1:3)->flat; p$t2 # the same
[
[-1 -1 -1 -1]
[ 2 3 4 -1]
[ 5 6 7 -1]
]
pdl> $t3(0:2,1:2) .= $p(0:1,1:3)->transpose; p$t3
[
[-1 -1 -1 -1]
[ 2 4 6 -1]
[ 3 5 7 -1]
]
pdl>
| [reply] [d/l] |
|
|
Thanks! Your answer is much better than what my want! I have seen some guys using so many clump and dummy(0,1) making the code very ugly and obscure. Your method is very good!
| [reply] |
Re: how to self define a operator (private method)
by LanX (Saint) on Oct 22, 2019 at 09:21 UTC
|
my $meth = sub {
$_[0] .= $_[1]->reshape($_[0]->dims)
};
And call it with
$t(1:2,0)->$meth( $p(0,1:2) )
from inside the same scope (untested)
This should come close to what you want.
HTH!
update
demo
DB<9> $op = sub { $_[0] + $_[1] }
DB<10> p 4->$op(5)
9
DB<11>
| [reply] [d/l] [select] |
|
|
Great! It is a good method. Thanks!
| [reply] |
Re: how to self define a operator
by LanX (Saint) on Oct 22, 2019 at 14:27 UTC
|
no one mentioned it yet, but in case you don't really need a binary operator, you can go for a normal function, because arguments are "passed by alias" in Perl.
DB<11> sub op { $_[0] += $_[1] }
DB<12> $x=4
DB<13> op($x,5)
DB<14> p $x
9
DB<15>
as you can see, you can change the states of passed variables.
That's normally the most maintainable approach, especially when combined with a good name for the operation.
| [reply] [d/l] |
|
|
Thanks, it is a good idea.
| [reply] |
Re: how to self define a operator
by rjt (Curate) on Oct 22, 2019 at 06:19 UTC
|
What you want to do would require modifying the language with new syntax. Hopefully needless to say, such endeavors are difficult, dangerous, and likely to be a waste of time, even if you are already a language specialist. To wit, the ~~ (smartmatch) binary operator was added to a public release almost 12 years ago, and it's still not stable.
You might be able to hack something together with source filters that sort of works in limited cases, but please don't. Odds of something like that breaking in simultaneously spectacular and sneaky fashion are unacceptably high for anything other than toy programs.
Would you mind sharing more details on what you are actually trying to accomplish (apart from inventing syntax)? A proper description of what you are actually working on would help us help you. There may well be an easy, elegant solution in pure Perl.
| [reply] [d/l] |
|
|
Thank you very much for your reply!
What I want to do is making the PDL more simple, as simple as matlab :D.
for example, if we want to transfer the values from $t(1:4,0,0) to $d1(0,0:3), we can not write as below, because the dimensions are not same.
$d1(0,0:3) .= $t(1:4,0,0);
We have to write as this:
$d1(0,0:3) .= $t(1:4,0,0)->reshape($d1(0,0:3)->dims);
So I think if I can generate a "_=" which equal to .= $t(1:4,0,0)->reshape($d1(0,0:3)->dims or using a new method "rp" as $d1(0,0:3)->rp($t(1:4,0,0));
| [reply] [d/l] [select] |
Re: how to self define a operator
by ikegami (Patriarch) on Oct 22, 2019 at 14:27 UTC
|
| [reply] [d/l] [select] |
|
|
Interesting, I will learn that, thanks.
| [reply] |