Andrew Newby
Andrew Newby

Reputation: 5197

Devel::Peek output results in STDERR

I'm trying to work out why my debugging from Devel::Peek::Dump isn't showing in my log file. I'm just doing this to pass the STDERR output:

open (STDERR, ">>/home/chambres/web/foo.org/public_html/cgi-bin/links/admin/stripe-booking.log") || die $!;

...and then this in my script:

use Devel::Peek;
print STDERR "name AFTER encoded: \n";
Dump($add_common->{name});

All I get in the log file is:

name AFTER encoded:

I know $add_common->{name} has a value, so I'm a bit confused as to why its not showing up. I'm trying to see some debug output from someone running a live script.

Upvotes: 2

Views: 140

Answers (1)

ikegami
ikegami

Reputation: 385789

Dump writes to fd 2. STDERR originally wraps fd 2, so something must have changed STDERR to get the behaviour you observe.

As you can see, redirecting STDERR works fine when STDERR is associated with fd 2:

$ perl -M5.010 -e'
   use Devel::Peek qw( Dump );
   open STDERR, ">>", "a" or die $!;
   say fileno(STDERR);
   Dump(undef);
'
2

$ cat a
SV = NULL(0x0) at 0x55d63aab13b0
  REFCNT = 2147483637
  FLAGS = (READONLY,PROTECT)

No so much when STDERR is associated with fd 3:

$ perl -M5.010 -e'
   use Devel::Peek qw( Dump );
   local *STDERR;
   open STDERR, ">>", "b" or die $!;
   say fileno(STDERR);
   Dump(undef);
'
3
SV = NULL(0x0) at 0x56050b00b3b0
  REFCNT = 2147483637
  FLAGS = (READONLY,PROTECT)

$ cat b

You could create a handle for fd 2, and redirect it.

$ perl -M5.010 -e'
   use Devel::Peek qw( Dump );
   open(my $fd2, ">&=", 2) or die $!;
   say fileno($fd2);
   open $fd2, ">>", "c" or die $!;
   say fileno($fd2);
   Dump(undef);
'
2
2

$ cat c
SV = NULL(0x0) at 0x5582af5dc3b0
  REFCNT = 2147483637
  FLAGS = (READONLY,PROTECT)

Since that changes the fd 2 of the process, the above workaround would affect Apache in its entirety in a mod_perl setting.

It sounds like you're primarily interested in the internal storage format used by a string. If so, you can get it using

utf8::is_utf8($s)

It returns true if the string is using the "upgraded" storage format (the SVf_UTF8 flag is set).

It returns true if the string is using the "downgraded" storage format (the SVf_UTF8 flag is clear). Presumably, it also returns false if the scalar doesn't contain a string.

But you're almost garanteed to be doing something wrong. If you're trying to work around a bug in an XS module, all you need is utf8::upgrade and/or utf8::downgrade.

Upvotes: 4

Related Questions