[pm-h] Using Moose Attributes In Regular Expressions - Question Regarding Magic ${\( ... )}

G. Wade Johnson gwadej at anomaly.org
Wed Aug 24 05:32:38 PDT 2016


It's fun watching people run through this odd piece of Perl magic.

The descriptions by Zaki Mughal are right on target.

Julian's example below covers one weird edge case though.

\( "a", "b" ) does not give a reference to an array, it gives an array
of references. The only explanations I've ever seen of that suggest
that we already have [] for array ref, so \( ) should do something
different.

I've never used the scalar ref version of this interpolation trick
before. I'll have to keep it in mind.

G. Wade

On Tue, 23 Aug 2016 17:01:43 -0500
Julian Brown via Houston <houston at pm.org> wrote:

> I need to know if I am an "old" dog trying to learn new tricks.
> 
> --------------------------------------
> $ cat ./doit.pl
> #!/usr/bin/perl
> 
> use strict;
> use warnings;
> 
> my $ref = \( "a", "b" );
> 
> print ":$ref:\n";
> print ":${$ref}:\n";
> 
> my $other = ("a", "b");
> 
> print "other :$other:\n";
> 
> $ ./doit.pl
> Useless use of a constant (a) in void context at ./doit.pl line 11.
> :SCALAR(0xaf9998):
> :b:
> other :b:
> --------------------------------------
> 
> This is what confused me \( ).
> 
> I think I am learning a new thing (not a trick).
> 
> The "use warnings" is enlightening.
> 
> I never really ever used a list in a scalar context before, in a
> scalar context it always returns the last item.   The warning is
> telling me that I am essentially throwing away the value of "a".
> 
> Julian
> 
> 
> 
> On Tue, Aug 23, 2016 at 4:08 PM, Zakariyya Mughal via Houston <
> houston at pm.org> wrote:
> 
> > On 2016-08-23 at 15:16:42 -0500, Robert Stone wrote:
> > > Greetings,
> > >
> > > Wow,
> > > https://metacpan.org/pod/distribution/perlsecret/lib/perlsecret.pod
> > is
> > > a treasure trove of goodies!  Thanks for sharing that.
> > >
> > > I believe this is the part of the documentation that stands out
> > > to me as most relevant:
> > >
> > >         *This is a container, or circumfix operator. The
> > > expression
> > inside
> > > the [] is run in list context, stored in an anonymous array,
> > > which is immediately dereferenced by @{}.*
> > >
> > > The "trick" here, as you pointed out, is the ${ } circumfix
> > > ScalarRef dereference.  However, in order to use it we have to
> > > have,
> > unsurprisingly,
> > > a ScalarRef, hence the need for \( ) to convert the return value
> > > of $object->foo first into a ScalarRef and then usage of ${ } for
> > > both dereferencing it back and that tasty circumfixing action
> > > (which is higher in precedence then the regex-ing, which is why
> > > this code snippet works)!
> > >
> > > Does that sound about right?
> >
> > Yep! However, I believe that the `${}` evaluation inside of `m//`
> > is due to interpolation rather than precedence. In `perldoc
> > perlop`, Perl puts terms
> > (e.g., quote-like operators and variables) higher than anything
> > else and these get processed left to right.
> >
> > You can also used B::Concise to see how Perl parses the expression:
> >
> >   perl -MO=Concise -e 'qr/before\Q${\( $object->foo )}\Eafter/;'
> >
> > Really fascinating stuff to play around with!
> >
> > Cheers,
> > - Zaki Mughal
> >
> > >
> > > Best Regards,
> > > Robert Stone
> > >
> > > On Tue, Aug 23, 2016 at 2:57 PM, Zakariyya Mughal
> > > <zaki.mughal at gmail.com
> > >
> > > wrote:
> > >
> > > > On 2016-08-23 at 14:35:38 -0500, Robert Stone via Houston wrote:
> > > > > Greetings,
> > > > >
> > > > > You are correct in the sense that $object->foo actually calls
> > > > > a
> > method
> > > > > "foo" created via Moose Magic that returns the value of the
> > > > > foo
> > > > attribute.
> > > > > Good call!
> > > > >
> > > > > Are you thinking that given the above, the \( ) business makes
> > > > $object->foo
> > > > > a coderef, and then ${ } executes it because it dereferences
> > > > > it?
> > Given
> > > > > that, why does this not match:
> > > > >
> > > > > if( $some_value =~ m/\Q$object->foo\E/ ) {
> > > > >
> > > > > While this does:
> > > > >
> > > > > if( $some_value =~ m/\Q${\( $object->foo )}\E/ ) {
> > > > >
> > > > > Is that ${ } "protecting" the $object->foo so that the regex
> > > > > engine
> > > > doesn't
> > > > > see it as regex-y?
> > > >
> > > > Not a coderef, but a scalar ref. It is similar to the approach
> > > > used by the baby cart operator:
> > > > <https://metacpan.org/pod/perlsecret#Baby-cart
> > >.
> > > >
> > > >   @{[ ]}
> > > >
> > > > Reading inside out:
> > > >
> > > >  - [ ... ]  : turn into an ArrayRef
> > > >  - @{ ... } : circumfix ArrayRef dereference
> > > >
> > > > So that approach for the regexp does:
> > > >
> > > >  - \ ... : turn into a reference (unary \ operator)
> > > >  - ${ ... } : circumfix ScalarRef dereference
> > > >
> > > > I use the baby cart operator enough that I have added a line in
> > > > my
> > vimrc
> > > > to make it work with surround.vim: <https://github.com/zmughal/
> > > > vimrc/commit/ad7894dcbe273b0ecb9703db88b51aa9a33d7f0c>.
> > > >
> > > >  Cheers,
> > > >  - Zaki Mughal
> > > >
> > > > >
> > > > > Best Regards,
> > > > > Robert Stone
> > > > >
> > > > > On Tue, Aug 23, 2016 at 2:19 PM, Julian Brown via Houston <
> > > > houston at pm.org>
> > > > > wrote:
> > > > >
> > > > > > I am not familiar with Moose, but am not convinced this is
> > specific to
> > > > > > Moose.
> > > > > >
> > > > > > I assume $object->foo is really a method call that returns
> > > > > > the foo attribute?  Or is it like a hash value?
> > > > > >
> > > > > >
> > > > > > • [root at julian64:~/work]# cat doit.pl
> > > > > > #!/usr/local/cpanel/3rdparty/bin/perl
> > > > > >
> > > > > > use strict;
> > > > > > use warnings;
> > > > > >
> > > > > > my $var = "A";
> > > > > > my $var_ref = \$var;
> > > > > >
> > > > > > print "VAR :${var}:\n";
> > > > > > print "VAR VAR :${$var_ref}:\n";
> > > > > >
> > > > > > Output is:
> > > > > >
> > > > > > VAR :A:
> > > > > > VAR VAR :A:
> > > > > >
> > > > > > I think we are in the same realm perhaps the parens inside
> > > > > > the ${}
> > is
> > > > > > necessary to execute the method?
> > > > > >
> > > > > > Julian
> > > > > >
> > > > > >
> > > > > >
> > > > > > On Tue, Aug 23, 2016 at 2:02 PM, Robert Stone via Houston <
> > > > houston at pm.org>
> > > > > > wrote:
> > > > > >
> > > > > >> Greetings,
> > > > > >>
> > > > > >> I find myself needing to use the value of a Moose
> > > > > >> Attribute in a
> > > > regular
> > > > > >> expression every now and then.  Typically I accomplish
> > > > > >> this via
> > > > (warning
> > > > > >> that all examples are very contrived and may contain bugs):
> > > > > >>
> > > > > >> *Sample Using Variable Assignment First*
> > > > > >>
> > > > > >> my $value = $my_moose_object->attribute;
> > > > > >> if( $some_value =~ m/\Q$value/ ) {
> > > > > >>
> > > > > >> Needless to say this isn't the most efficient/easiest to
> > > > > >> work
> > with.
> > > > > >> Given that fact, I've come across a way of using Moose
> > > > > >> Attributes
> > > > directly
> > > > > >> in regular expressions:
> > > > > >>
> > > > > >> *MyObject*
> > > > > >>
> > > > > >> package MyObject;
> > > > > >>
> > > > > >> use Moose;
> > > > > >>
> > > > > >> has foo => ( is => 'ro', isa => 'Str' );
> > > > > >>
> > > > > >> ...;
> > > > > >>
> > > > > >> *Script That Consumes MyObject*
> > > > > >>
> > > > > >> my $object = MyObject->new( foo => 'Value' );
> > > > > >> if( $some_value =~ m/\Q${\( $object->foo )}\E/ ) {
> > > > > >>
> > > > > >>
> > > > > >> This works, but frankly I'm not entirely certain why.
> > > > > >> From the documentation at
> > > > > >> http://perldoc.perl.org/perlre.html#Regular-
> > > > Expressions
> > > > > >> I have:
> > > > > >>
> > > > > >> \Q          quote (disable) pattern metacharacters until \E
> > > > > >> \E          end either case modification or quoted
> > > > > >> section, think
> > vi
> > > > > >>
> > > > > >> Great, that makes sense.
> > > > > >>
> > > > > >> But what magic is the ${\( ... )} doing here?  I'd be most
> > grateful if
> > > > > >> anyone had some insight and could share it with us!
> > > > > >>
> > > > > >> Best Regards,
> > > > > >> Robert Stone
> > > > > >>
> > > > > >>
> > > > > >>
> > > > > >> _______________________________________________
> > > > > >> Houston mailing list
> > > > > >> Houston at pm.org
> > > > > >> http://mail.pm.org/mailman/listinfo/houston
> > > > > >> Website: http://houston.pm.org/
> > > > > >>
> > > > > >
> > > > > >
> > > > > > _______________________________________________
> > > > > > Houston mailing list
> > > > > > Houston at pm.org
> > > > > > http://mail.pm.org/mailman/listinfo/houston
> > > > > > Website: http://houston.pm.org/
> > > > > >
> > > >
> > > > > _______________________________________________
> > > > > Houston mailing list
> > > > > Houston at pm.org
> > > > > http://mail.pm.org/mailman/listinfo/houston
> > > > > Website: http://houston.pm.org/
> > > >
> > > >
> > _______________________________________________
> > Houston mailing list
> > Houston at pm.org
> > http://mail.pm.org/mailman/listinfo/houston
> > Website: http://houston.pm.org/
> >


-- 
The mere formulation of a problem is far more essential than its
solution, which may be merely a matter of mathematical or experimental
skills. -- Albert Einstein


More information about the Houston mailing list