Re: output differs in perl version
by moritz (Cardinal) on Jul 04, 2011 at 08:02 UTC
|
This code works in perl 5.10.1.. but not in perl 5.8.8
How does it fail with 5.8.8?
I cant upgrade it to latest version, since i m running under my college server.
Yes you can(*), with App::perlbrew. It lets you easily build and install a perl in your home directory.
(*) unless your home directory does not allow exectuable files, but that's only rarely the case.
| [reply] |
Re: output differs in perl version
by Corion (Patriarch) on Jul 04, 2011 at 08:04 UTC
|
| [reply] |
Re: output differs in perl version
by graff (Chancellor) on Jul 04, 2011 at 09:00 UTC
|
I happen to have access to an old freebsd machine that still runs 5.8.8 (hasn't been updated in ages...) and I see that the output looks like stuff that you've shown in earlier posts on this same general topic:
Well, because I first learned about the (?=...) regex construct (referred to as a "positive look-ahead assertion") when using 5.8.8, I have to assume there's something tricky and unexpected that happens when the look-ahead expression can match variable-length strings (and this was apparently fixed in 5.10).
If you really have to construct word trigrams in 5.8.8, I guess you'll have to do something other than a pure regex solution relying that sort of syntax. The easier way to do word n-grams is to use split:
my $str1 = q/It is a guide to action which ensures that the military a
+lways obey the commands of the party./;
my $str2 = q/It is a guide to action that ensures that the military wi
+ll forever heed Party commands is a guide./;
for my $str ( $str1, $str2 ) {
print "=== input is [$str] ===\n";
my @words = split / /, $str;
while ( @words >= 3 ) {
print join( " ", @words[0..2] ), "\n";
shift @words;
}
print "\n";
}
Of course, if that doesn't satisfy the contrived conditions of a given homework assignment ("You must not use 'split'! And you must use Perl 5.8.8!!"), well, that's a shame. The instructor ought to know better (or shouldn't be so deliberately mean to the poor students...) | [reply] [d/l] [select] |
|
But you always can implement the algorithm in a way that does work in 5.8.8. For example like this:
while ( $str1 =~ /^(\S+\s+)(\S+\s+\S+)(.*)$/ ) {
print "$1$2\n";
$str1 = "$2$3";
$n++;
}
Alternatively, you could use $' (${^POSTMATCH} doesn't work in 5.8.8):
while ( $str1 =~ /^(\S+\s+)(\S+\s+\S+)/ ) {
print "$1$2\n";
$str1 = "$2$'";
$n++;
}
| [reply] [d/l] [select] |
|
| [reply] |
Re: output differs in perl version
by Anonymous Monk on Jul 04, 2011 at 08:38 UTC
|
hi there, ... So, Any suggestion or modifications to achieve the same output in 5.8.8..
See Re^7: count the maximum no.of occurence
What can you do about it? Don't use the feature that triggers this bug in 5.8.8.
| [reply] |
Re: output differs in perl version
by AnomalousMonk (Archbishop) on Jul 04, 2011 at 16:48 UTC
|
I see letter-by-letter overlapping with the code of the OP when run under ActiveState 5.8.9, and I assume this is the way the code 'doesn't work' under sarvan's 5.8.8. (As others have commented, it would be nice if sarvan would actually say how the code 'doesn't work'.)
The following modification produces the same output in AS 5.8.9 and Strawberries 5.10.1.5 and 5.12.3.0 (don't ask me just why; the answer is presumably in one of the perldelta docs):
>perl -wMstrict -le
"my $str1 = q/It is a guide to action which ensures that the /
. q/military always obey the commands of the party./
;
;;
my $n = 0;
while ($str1 =~ m{ (?= (\b \S+ \s+ \S+ \s+ \S+ \b)) }xmsg) {
my $t1 = $1;
print qq{$t1};
$n++;
}
;;
print qq{No of matching is: $n};
"
It is a
is a guide
a guide to
guide to action
to action which
action which ensures
which ensures that
ensures that the
that the military
the military always
military always obey
always obey the
obey the commands
the commands of
commands of the
of the party
No of matching is: 16
Note: The 5.10+ versions don't need the \b assertions to produce the same result.
Update: Actually, the second \b assertion in the regex above is redundant. The regex
m{ (?= (\b \S+ \s+ \S+ \s+ \S+)) }xmsg
gives the output of the OP (which I think is what sarvan wants) under all Perl versions listed above.
| [reply] [d/l] [select] |
Re: output differs in perl version
by ambrus (Abbot) on Jul 04, 2011 at 21:55 UTC
|
According to my tests, perl 5.12.3 gives the following incorrect output (same as in your post):
It is a
is a guide
a guide to
guide to action
to action which
action which ensures
which ensures that
ensures that the
that the military
the military always
military always obey
always obey the
obey the commands
the commands of
commands of the
of the party.
However, perl 5.14.0 gives the correct output:
It is a
t is a
is a guide
s a guide
a guide to
guide to action
uide to action
ide to action
de to action
e to action
to action which
o action which
action which ensures
ction which ensures
...
Does someone have a perl 5.12.4 handy to test whether this bug is still present in the 5.12 branch?
| [reply] [d/l] [select] |
|
Installed ActivePerl 5.12.4. It's buggy, emitting the same as 5.12.3.
| [reply] |
|
Yeah, the bug is in the Perls after 5.8.8 not in 5.8.8. If the original output is what is desired, then simply add \b near the front of the regex. That should work in versions even that don't have that bug.
| [reply] |
Re: output differs in perl version
by ikegami (Patriarch) on Jul 05, 2011 at 01:46 UTC
|
I cant upgrade it to latest version, since i m running under my college server.
Surely not true. One doesn't need any special permissions to install Perl. It's even easy using App::perlbrew.
Any suggestion or modifications to achieve the same output in 5.8.8.
my $n = 0;
while ( $str1 =~ /(\S+\s+)(?=(\S+\s+\S+))/g ) {
print "$t1$t2\n";
++$n;
}
or
my @words = split ' ', $str;
my $n = @words - 2;
print "@words[$_+0, $_+1, $_+2]\n"
for 0..$n-1;
This code works in perl 5.10.1.. but not in perl 5.8.8.
Although 5.8.8 is not giving the output you want, it's the one giving the correct output for the given code. | [reply] [d/l] [select] |