artifact has asked for the wisdom of the Perl Monks concerning the following question:

i find an error message saying "cant use string<1> while strict ref"? please also say how can we find the number of matches for any regexp.

#! usr/bin/perl use warnings; use strict; my $x = "Mmm...donut, thought Homer"; $x =~ /^(Mmm|Yech)\.\.\.(donut|peas)/; # matches foreach my $expr (1..$#-) { print "Match $expr: '${$expr}' at position ($-[$expr],$+ [$expr])\n +"; }

Replies are listed 'Best First'.
Re: can't use string refs while "strict refs"
by davido (Cardinal) on Jul 30, 2012 at 05:15 UTC

    Here's a little trick that might have helped you to answer the first part of your question yourself, much faster than composing the node that you post here, and waiting for a meaningful answer to come back:

    use warnings; use strict; use diagnostics; # <------------------------- Important line here. my $x = "Mmm...donut, thought Homer"; $x =~ /^(Mmm|Yech)\.\.\.(donut|peas)/; # matches foreach my $expr (1..$#-) { print "Match $expr: '${$expr}' at position ($-[$expr],$+ [$expr])\n +"; }

    The output you get will be:

    Can't use string ("1") as a SCALAR ref while "strict refs" in use at m +ytest.pl line 11 (#1) (F) Only hard references are allowed by "strict refs". Symbolic references are disallowed. See perlref. Uncaught exception from user code: Can't use string ("1") as a SCALAR ref while "strict refs" in use +at mytest.pl line 11. at mytest.pl line 11.

    Notice how it helpfully guides you to perlref? You can take that suggestion to your own command line by typing, "perldoc perlref, or by visiting perldoc.perl.org and typing in perlref. In that document when you search for "symbolic references" you will find the following:

    Symbolic references

    We said that references spring into existence as necessary if they are undefined, but we didn't say what happens if a value used as a reference is already defined, but isn't a hard reference. If you use it as a reference, it'll be treated as a symbolic reference. That is, the value of the scalar is taken to be the name of a variable, rather than a direct link to a (possibly) anonymous value.

    People frequently expect it to work like this. So it does.

    $name = "foo"; $$name = 1; # Sets $foo ${$name} = 2; # Sets $foo ${$name x 2} = 3; # Sets $foofoo $name->[0] = 4; # Sets $foo[0] @$name = (); # Clears @foo &$name(); # Calls &foo() (as in Perl 4) $pack = "THAT"; ${"${pack}::$name"} = 5; # Sets $THAT::foo without eval

    This is powerful, and slightly dangerous, in that it's possible to intend (with the utmost sincerity) to use a hard reference, and accidentally use a symbolic reference instead. To protect against that, you can say

    use strict 'refs';

    and then only hard references will be allowed for the rest of the enclosing block.

    Then your question might instead be seeking clarification on what that means. perlref also points you to perlreftut, which is a shorter and somewhat kinder entry point to references. After spending a few minutes with those documents you'll come to a more thorough understanding than you could hope to obtain by reading a few pithy replies here.


    Dave

Re: can't use string refs while "strict refs"
by Athanasius (Archbishop) on Jul 30, 2012 at 03:04 UTC

    Please wrap code in <code>...</code> tags. See How do I post a question effectively?. Also, the code you quote comes from perlretut. It would have been helpful if you had mentioned this.

    i find an error message
    #! perl use strict; use warnings; my $x = "Mmm...donut, thought Homer"; $x =~ /^(Mmm|Yech)\.\.\.(donut|peas)/; # matches foreach my $expr (1 .. $#-) { printf "Match %s: '%s' at position (%d, %d)\n", $expr, substr( $x, $-[$expr], $+[$expr] - $-[$expr] ), # fixes t +he error $-[$expr], $+[$expr]; }
    please also say how can we find the number of matches for any regexp.
    print "Number of matches: $#-\n";

    HTH,

    Athanasius <°(((><contra mundum

      Thanks for the help,I now think am capable of understanding Hard references and symbolic reference.. also I'll be aware of the format to post

Re: can't use string refs while "strict refs"
by Marshall (Canon) on Jul 30, 2012 at 06:34 UTC
    You have sort of copied an example straight out of the Perlretut without really understanding what it does.

    I would say that not everything that you read in the tutorials is common - there are some very complicated and rare things - and this is one of them!

    This is so rare, that I don't think that it is worth delving into the mind-numbing details. VERY seldom do you even care in the slightest about the pos(position) of a match - that is 'C' thinking.

    Perl regex is most commonly used to capture stuff that is between other stuff and whether this happens at index 5 or 95 usually just doesn't make any difference at all. The purists would say: "well sometimes it does matter" and I would agree with them. What I am saying here is that the pos() almost always does not matter.

    I show some more common ideas in Perl below.

    #!usr/bin/perl use warnings; use strict; my $x = "Mmm...donut, thought... Homer...Yech...peas"; my @matches = $x =~ /(Mmm|Yech)\.\.\.(donut|peas)/g; print "number of matches is: ".@matches."\n"; print "matches are: @matches\n"; print "\n"; $x = "MmmABCdonut, thought... HomerABXYechABYpeas"; my @moreMatches = $x =~ /(?:Mmm|Yech)(...)(?:donut|peas)/g; print "moreMatches number: ".@moreMatches,"\n"; print "@moreMatches\n"; __END__ prints: number of matches is: 4 matches are: Mmm donut Yech peas moreMatches number: 2 ABC ABY
Re: can't use string refs while "strict refs"
by Anonymous Monk on Jul 30, 2012 at 03:57 UTC

    Have you read what strict#strict refs documentation has to say?

    Also, you forgot to surround your code with <code> or <c> tags

      Thank you for your advice, further no such silly questions will be posted by me untill I have gone through the documnetation and also I'll be careful about the format ... I am using Beginning perl to learn perl as a beginner. can you tell me that am i going on the right path or do I need to follow some other books/references??

        It's not a bad book, but it's perhaps a little dated. Perl has moved on somewhat since it was published. Ovid's book (confusingly also called Beginning Perl!) is more in tune with current best practices; it's not going to be released until September, but you can read much of it online already.

        chromatic's Modern Perl is also well worth a read. Although it does go right back to Perl basics, it's written as much for experienced Perl programmers as it is for new ones, so you might find that it takes you from simple concepts to complex ones a little too quickly. Still it's well worth reading this one after you've finished learning the basics.

        perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
Re: can't use string refs while "strict refs"
by tobyink (Canon) on Jul 30, 2012 at 07:16 UTC

    Perhaps something like this:

    use strict; use warnings; my $x = "Mmm...donut, thought Homer"; if (my @matches = $x =~ /^(Mmm|Yech)\.\.\.(donut|peas)/) { unshift @matches => undef; foreach my $expr (1..$#-) { print "Match $expr: '$matches[$expr]' at position ($-[$expr],$ ++[$expr])\n"; } }

    Note the trick is to capture the return value of the =~ into an array (which I've called @matches above).

    Trick number two is to unshift a dummy value into $matches[0]. This is because arrays are indexed from 0 and regex matches are numbered from 1. Unshifting the dummy value makes @matches line up better with $- and $+.

    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'