in reply to Re: passing qr//'d regexp via Perl/Tk Entry widget
in thread passing qr//'d regexp via Perl/Tk Entry widget

I guess I need to clarify why the behavior of this script puzzles me, and say a bit more about what I ulimately want to do:

This script puzzles me because if I wrote:
my $string = "foobarbaz"; my $exp = qr/foo/; print STDOUT "matching $exp...\n"; print STDOUT "match!\n" if $string =~ m/$exp/;
I would get what I expect...i.e. I would see:
matching (?-xism:foo)... match!
But when the regexp object qr/foo/ is instead assigned to the variable $exp via the get method, it (seems) to cease to be a regexp object. In fact, it seems to become the string literal 'qr/foo/'. So what is the get method doing to my regexp object and how can I make it stop?

The other thing is that I want the user to have the _choice_ to pass a regexp in a qr//, in double quoted string, or in single quoted string, as he or she sees fit given the context. There's good reason for this. For instance, many users may not know that they can pass modifiers (say /s) via the "(?:s foo)" "span" operator, but may know that they can get the same effect by writing qr/foo/s. In otherwords, I want it to be true that my Perl/Tk app allows "more than one way to do it." Otherwise "requiring" users to enter, say, everthing as a qr// object would be ok.

Thanks!

Replies are listed 'Best First'.
Re^3: passing qr//'d regexp via Perl/Tk Entry widget
by crashtest (Curate) on Jun 23, 2005 at 23:42 UTC
    But when the regexp object qr/foo/ is instead assigned to the variable $exp via the get method, it (seems) to cease to be a regexp object. In fact, it seems to become the string literal 'qr/foo/'. So what is the get method doing to my regexp object and how can I make it stop?
    You're hitting the nail on the head, but not seeing it, I think. When you type "qr/foo/" into your entry widget, it is just a string. It never "ceases" to be a regular expression object - it never was one. You might have typed anything into your text box, a limmerick or a dirty word or anything. Just because the text is "qr/foo/", and happens to be a string that stands for a regular expression object in the Perl language is immaterial. The program won't look at the text and say, aha, this is a perl construct. It's just text.

    This is completely different from writing my $exp = qr/foo/; in your perl script. This is part of your program (and not your program input), and perl knows how to parse this. If, instead of my $exp = qr/foo/; you wrote my $exp = "qr/foo/";, you would get the same behavior as when the regex is passed via your text entry widget.

    If you want Perl to parse and interpret the entered text as a chunk of Perl code, you need to use the string version of eval. That tells perl that the text passed in is more than text, and to evaluate it as a Perl expression. I hope this makes sense.

    As for allowing a user several ways to pass a regular expression, you should read the text entered and adjust your processing accordingly, like [id://injunjoel] suggests. Something like this (completely untested):
    my $regexp = undef; my $entered_text = $regexp_entry -> get(); if ($entered_text =~ m!^qr/!){ # User has passed a "qr//" type regex: $regexp = eval $entered_text; } else{ # User has passed a straight regular expression $regexp = m/$entered_text/; }
    Note that there is no need in the "else" branch for the user to have enclosed their code in single- or double-quotes. You are reading text from the widget, then using that text to construct a regular expression at run time.

      That's extremely helpful. Answers my questions exactly.

      thanks very much.