Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Not a bug, but did perl really mean that? #40

Closed
p5pRT opened this issue Jun 3, 1999 · 18 comments
Closed

Not a bug, but did perl really mean that? #40

p5pRT opened this issue Jun 3, 1999 · 18 comments

Comments

@p5pRT
Copy link

@p5pRT p5pRT commented Jun 3, 1999

Migrated from rt.perl.org#842 (status was 'resolved')

Searchable as RT842$

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Jun 3, 1999

From jmh@mail.msen.com

Truth in perl can be a problem when dealing with bitwise operators.
A scalar is true if it is not '' or "0" or undef.

If we want to work with pipes, we play with select() a lot.

pipe(A,B);
pipe(C,D);

# Setup pipes, fork, etc.

vec($ready_a, fileno(A), 1) = 1;
vec($ready_c, fileno(C), 1) = 1;

#Get ready for select
vec($rin, fileno(A), 1) = 1;
vec($rin, fileno(C), 1) = 1;

select($rout=$rin, undef, undef, 10);

In C, if we want to see if a particular selector is set, we can say​:

if ($rout & $ready_a) { # do something useful }

We can't do this in perl because the return of ($rout & $ready_a)
is "\0" when nothing is set.

This can be gotten around by saying​:
if (($rout & $ready_a) eq $ready_a) { # do something useful }

Unfortunately, I don't know if this is good for 100% of the cases
since the items set by the vec() may create strings of differing
length (?). E.g. the return may be "\0\0".

Trying to evaluate things in a numeric context using == doesn't
seem to do the right thing.

What would be most useful is, when dealing with vectors, to
define TRUE to not include the string of all "\0" characters.

I realize that using the bitcounting operator is a useful workaround,
but it is also inelegant.

--
Jeffrey Haas -+- jmh@​msen.com -+- http​://www.msen.com/~jmh
/\/\sen, Inc. "Michigan's Best Run Internet Service Provider."

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Mar 20, 2000

From [Unknown Contact. See original ticket]

Jeff,

You pointed out that a string consisting of \0 bytes isn't false,
and so it's hard to test for in Perl. Solutions are​:
  if ($mask =~ /^\0*$/)
and
  use IO​::Select;

I've marked the bugreport as closed.

Cheers;

Nat

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Mar 20, 2000

From [Unknown Contact. See original ticket]

Jeff,

You pointed out that a string consisting of \0 bytes isn't false,
and so it's hard to test for in Perl. Solutions are​:
if ($mask =~ /^\0*$/)

I don't think that that does what you wish it did.

  open(NEWFH, ">/dev/null") || die $!;
  $mask = '';
  vec($mask, fileno(NEWFH), 1) = 1;
  vec($mask, fileno(STDOUT), 1) = 1;
  if ($mask =~ /^\0*$/) {
  print "No bits here!\n";
  } else {
  print "Got those bits!\n";
  }

Prints "No bits here." See why? :-)

--tom

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Mar 20, 2000

From [Unknown Contact. See original ticket]

Tom Christiansen writes​:

chr( (1 << 1) | (1 << 3) ) eq "\n"

and "\n" always matches /^\0*$/

Zap!

Oh bollocks. Change the regexp​:
  /\A\0*\Z/

Thanks for pointing that out, Tom.

Nat

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Mar 20, 2000

From @tamias

On Mon, Mar 20, 2000 at 09​:20​:23PM -0700, Nathan Torkington wrote​:

Tom Christiansen writes​:

chr( (1 << 1) | (1 << 3) ) eq "\n"

and "\n" always matches /^\0*$/

Zap!

Oh bollocks. Change the regexp​:
/\A\0*\Z/

Thanks for pointing that out, Tom.

I think that should be \z. \Z can also match before a newline.

Ronald

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Mar 20, 2000

From [Unknown Contact. See original ticket]

Ronald J Kimball writes​:

Oh bollocks. Change the regexp​:
/\A\0*\Z/

I think that should be \z. \Z can also match before a newline.

That's it, I'm taking up Python.

Nat

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Mar 20, 2000

From [Unknown Contact. See original ticket]

I think that should be \z. \Z can also match before a newline.

That's right. That's why I, and even moreso Greg, went it and fixed a
million Perl libraries that were doing /^blah$/ and meaning /\Ablah\z/.
The \Z is seductive for parallism. Just don't write /\ablah\z/. Ding.

--tom

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Mar 20, 2000

From [Unknown Contact. See original ticket]

On Mar 20, Nathan Torkington said​:

Ronald J Kimball writes​:

Oh bollocks. Change the regexp​:
/\A\0*\Z/

I think that should be \z. \Z can also match before a newline.

That's it, I'm taking up Python.

Yeah, good idea. Quadruple backslash to get a single backslash in a
regex. Unless you use raw string quoting. Nevermind.

--
MIDN 4/C PINYAN, NROTCURPI, US Naval Reserve japhy@​pobox.com
http​://www.pobox.com/~japhy/ http​://pinyaj.stu.rpi.edu/
PerlMonth - An Online Perl Magazine http​://www.perlmonth.com/
The Perl Archive - Articles, Forums, etc. http​://www.perlarchive.com/

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Mar 20, 2000

From [Unknown Contact. See original ticket]

Tom Christiansen wrote​:

The \Z is seductive for parallism.

Only when using \A. There is no need for \A in /\Ablah\z/ since it is
only meaningful with /m.

  /^blah\z/

I find the lack of symmetry here makes the intent clearer.

--
Rick Delaney
rick.delaney@​home.com

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Mar 20, 2000

From [Unknown Contact. See original ticket]

Tom Christiansen wrote​:

The \Z is seductive for parallism.

Only when using \A. There is no need for \A in /\Ablah\z/ since it is
only meaningful with /m.

/^blah\z/

I find the lack of symmetry here makes the intent clearer.

That's not correct. $* may be set.

--tom

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Mar 20, 2000

From [Unknown Contact. See original ticket]

Tom Christiansen wrote​:

That's not correct. $* may be set.

print "The meaning of deprecated in perl is ",
  (qw/crazy sensible/)[1],
  ".\n";

Set $[ appropriately.

--
Rick Delaney
rick.delaney@​home.com

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Mar 20, 2000

From [Unknown Contact. See original ticket]

Tom Christiansen wrote​:

That's not correct. $* may be set.

print "The meaning of deprecated in perl is ",
(qw/crazy sensible/)[1],
".\n";

Set $[ appropriately.

No, that's not the same. $[ is lexical. $* is global.
You can't do anything about what someone else did in code
you're not looking at.

--tom

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Mar 20, 2000

From [Unknown Contact. See original ticket]

Tom Christiansen wrote​:

Set $[ appropriately.

No, that's not the same. $[ is lexical. $* is global.
  ^^^^^^^^^^^^^
This, I didn't know, or if I ever did I promptly forgot since I never
use $[.

You can't do anything about what someone else did in code
you're not looking at.

You are correct. Does it not make more sense to remove such
action-at-a-distance behaviour rather than code around it?

--
Rick Delaney
rick.delaney@​home.com

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Mar 20, 2000

From [Unknown Contact. See original ticket]

You can't do anything about what someone else did in code
you're not looking at.

You are correct. Does it not make more sense to remove such
action-at-a-distance behaviour rather than code around it?

One does what one can, as one can. Right now, one can code
defensively. Spooky action at a distance is often disconcerting.
I don't know whether making $* lexical like $] is something we
could do yet.

--tom

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Mar 20, 2000

From [Unknown Contact. See original ticket]

Tom Christiansen wrote​:

One does what one can, as one can. Right now, one can code

And that is appreciated.

defensively. Spooky action at a distance is often disconcerting.
I don't know whether making $* lexical like $] is something we
could do yet.

I see no reason to ever go there. IMHO, it is time for $* to retire
gracefully. He's been deprecated long enough and the younger players /s
and /m seem to be competing quite nicely.

--
Rick Delaney
rick.delaney@​home.com

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Mar 28, 2000

From [Unknown Contact. See original ticket]

Is this right?

% P -MO=Showlex,retval -e 'sub retval { my $self = shift; my $n = sub { my $arg = shift; return $self->{$arg} } } '
Pad of lexical names for &retval has 5 entries
0​: SPECIAL #1 &PL_sv_undef
1​: PVNV (0x8193810) "$self"
2​: SPECIAL #1 &PL_sv_undef
3​: PVNV (0x81938a0) "$n"
4​: PVNV (0x81938ac) "&"
Pad of lexical values for &retval has 5 entries
0​: AV (0x81944f4) FILL -1
1​: NULL (0x80f522c)
2​: NULL (0x8193804)
3​: NULL (0x8193894)
4​: CV (0x81938b8) 0

What's all that well, stuff? And what's the thing whose name is
"&" all about? You run with Xref and it doesn't show up.

% P -MO=Xref -e 'sub retval { my $self = shift; my $n = sub { my $arg = shift; return $self->{$arg} } } '
File -e
  Subroutine (definitions)
  Package UNIVERSAL
  &VERSION s0
  &can s0
  &isa s0
  Package attributes
  &bootstrap s0
  Package main
  &retval s1
  Subroutine retval
  Package (lexical)
  $n i1
  $self i1
  Package main
  @​_ 1

Here are more.

% perl -MO=Showlex /tmp/testit
Pad of lexical names for comppadlist has 0 entries
Pad of lexical values for comppadlist has 1 entries
0​: SPECIAL #1 &PL_sv_undef
/tmp/testit syntax OK

% perl -MO=Showlex,start /tmp/testit
Pad of lexical names for &start has 27 entries
0​: SPECIAL #1 &PL_sv_undef
1​: PVNV (0x8193774) "$self"
2​: PVNV (0x81937f8) "$tag"
3​: PVNV (0x8193810) "$attr"
4​: PVNV (0x8193828) "$attrseq"
5​: PVNV (0x8193840) "$orig"
6​: SPECIAL #1 &PL_sv_undef
7​: SPECIAL #1 &PL_sv_undef
8​: SPECIAL #1 &PL_sv_undef
9​: SPECIAL #1 &PL_sv_undef
10​: SPECIAL #1 &PL_sv_undef
11​: PVNV (0x8194458) "$tmp"
12​: SPECIAL #1 &PL_sv_undef
13​: SPECIAL #1 &PL_sv_undef
14​: SPECIAL #1 &PL_sv_undef
15​: PVNV (0x81944dc) "$encoded"
16​: SPECIAL #1 &PL_sv_undef
17​: SPECIAL #1 &PL_sv_undef
18​: SPECIAL #1 &PL_sv_undef
19​: SPECIAL #1 &PL_sv_undef
20​: SPECIAL #1 &PL_sv_undef
21​: SPECIAL #1 &PL_sv_undef
22​: SPECIAL #1 &PL_sv_undef
23​: SPECIAL #1 &PL_sv_undef
24​: SPECIAL #1 &PL_sv_undef
25​: SPECIAL #1 &PL_sv_undef
26​: SPECIAL #1 &PL_sv_undef
Pad of lexical values for &start has 27 entries
0​: AV (0x81945e4) FILL -1
1​: NULL (0x80f56a8)
2​: NULL (0x8193768)
3​: NULL (0x8193804)
4​: NULL (0x819381c)
5​: NULL (0x8193834)
6​: NULL (0x819384c)
7​: NULL (0x8194404)
8​: NULL (0x8194428)
9​: NULL (0x8194440)
10​: NULL (0x8194464)
11​: NULL (0x819444c)
12​: NULL (0x8194488)
13​: NULL (0x81944b8)
14​: NULL (0x81944c4)
15​: NULL (0x81944d0)
16​: NULL (0x81944e8)
17​: NULL (0x819450c)
18​: NULL (0x819453c)
19​: NULL (0x8194548)
20​: NULL (0x8194560)
21​: NULL (0x8194518)
22​: NULL (0x819456c)
23​: NULL (0x8194578)
24​: NULL (0x8194584)
25​: NULL (0x819
[truncate --tchrist]

That was from this guy that you saw before​:

% cat /tmp/testit
sub start {
  my($self, $tag, $attr, $attrseq, $orig) = @​_;
  if ($tag eq 'a' && exists $attr->{href}) {
  if ($attr->{href} =~ s/\Q$from/$to/g) {
  # must reconstruct the start tag based on $tag and $attr.
  # wish we instead were told the extent of the 'href' value
  # in $orig.
  my $tmp = "<$tag";
  for (@​$attrseq) {
  my $encoded = encode_entities($attr->{$_});
  $tmp .= qq( $_="$encoded ");
  }
  $tmp .= ">";
  $self->output($tmp);
  return;
  }
  }
  $self->output($orig);
}

--tom

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Mar 28, 2000

From [Unknown Contact. See original ticket]

However, it blows up completely in the B​:CC case.

...

Finally, if your program does something like 'use Fcntl', you get
142 lines of the following form​:

....

Note that those two, at least, are not platform specific.

--tom

@p5pRT
Copy link
Author

@p5pRT p5pRT commented Mar 28, 2000

From [Unknown Contact. See original ticket]

This seems to better match expected usage and desirable properties.
Can anybody think of any good reason why the debugger should not
be fixed to work this way? (Actually, I've already got the patch,
but wanted to run the idea by the world first.)

Well, I've heard nothing, so here's the patch that implements this.

Inline Patch
--- perl5db.pl-presig	Tue Mar 14 18:42:13 2000
+++ perl5db.pl	Wed Mar 15 06:23:49 2000
@@ -346,16 +346,24 @@
     return 1;
 }
 
-if (-f $rcfile) {
-    safe_do("./$rcfile");
-} 
-elsif (defined $ENV{HOME} && -f "$ENV{HOME}/$rcfile") {
+{ 
+    my @sb;	# stat buff to check duplicate loading
+    if (defined $ENV{HOME} && -f "$ENV{HOME}/$rcfile") {
+	@sb = stat(_);
     safe_do("$ENV{HOME}/$rcfile");
-}
-elsif (defined $ENV{LOGDIR} && -f "$ENV{LOGDIR}/$rcfile") {
+    }
+    elsif (defined $ENV{LOGDIR} && -f "$ENV{LOGDIR}/$rcfile") {
+	@sb = stat(_);
     safe_do("$ENV{LOGDIR}/$rcfile");
-} 
+    } 
 
+    if (-f $rcfile) {
+	if (@sb && $sb[0] != (stat _)[0] && $sb[1] != (stat _)[1]) { 
+	    safe_do("./$rcfile");
+	}
+    } 
+
+}
 if (defined $ENV{PERLDB_OPTS}) {
     parse_options($ENV{PERLDB_OPTS});
 }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
1 participant