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

Zakariyya Mughal zaki.mughal at gmail.com
Tue Aug 23 14:08:17 PDT 2016


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/
> >
> >


More information about the Houston mailing list