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

Inspired by How to make an IO::Uncompress::Bunzip2 look like a GLOB
#!/usr/bin/perl -- use strict; use warnings; eval { STDOUT->print( "can print ", UNIVERSAL::can( \*STDOUT, 'print' ), +"\n" ); 1; } or print "$@\n"; require IO::Handle; print "can print ", STDOUT->can('print') || '', "\n"; print "can print ", *STDOUT{IO}->can('print'), "\n"; __END__ Can't locate object method "print" via package "IO::Handle" at - line +7. can print can print CODE(0x188ae88)
Is this a bug?

Replies are listed 'Best First'.
Re: IO::Handle UNIVERSAL::can STDOUT print
by ikegami (Patriarch) on Sep 04, 2009 at 06:10 UTC

    The first result is expected. You can't use a module you haven't loaded yet.

    The second result makes sense too. *STDOUT isn't a blessed reference. In fact, it's not a reference at all. Keep in mind that you are calling methods on something that isn't an object. can can't interrogate the class associated with the object since there isn't one.

    Similarly, \*STDOUT is a reference, but it's not blessed.

    *STDOUT{IO}, on the other hand, is indeed blessed into IO::Handle. can will report that the presence of IO::Handle::print as desired. All's good here too.

    What do you think is a bug?

    Cleaner test:

    #!/usr/bin/perl -- use strict; use warnings; $\="\n"; print "\\*STDOUT: ", \*STDOUT; print "*STDOUT: ", *STDOUT; print "*STDOUT{IO}: ", *STDOUT{IO}; print ''; for (1..2) { print "\\*STDOUT: ", (\*STDOUT) ->can('print') ||0; print "*STDOUT: ", *STDOUT ->can('print') ||0; print "*STDOUT{IO}: ", *STDOUT{IO} ->can('print') ||0; print ''; require IO::Handle; }
    \*STDOUT: GLOB(0x182a044) *STDOUT: *main::STDOUT *STDOUT{IO}: IO::Handle=IO(0x182a054) \*STDOUT: 0 *STDOUT: 0 *STDOUT{IO}: 0 \*STDOUT: 0 *STDOUT: 0 *STDOUT{IO}: CODE(0x18784f4)
      use IO::Handle; STDOUT->print("printing works\n"); __END__ printing works
        What about it?