in reply to Is it possible to distinguish contstants from normal subs?

Here's one that works. I'd be happy to replace it with something cleaner. C'mon PerlMonks, I know you can do it! Here's what I've got:

#!/usr/bin/perl -w use strict; sub is_constant { no strict 'refs'; my $name = shift; my $code = *{$name}{CODE}; # must have an empty prototype to be a constnat my $proto = prototype($name); return 0 unless defined $proto and not length $proto; # attempt to redefine - this will cause a warning for a # real constant that starts with "Constant" my $is_constant; local $SIG{__WARN__} = sub { $is_constant = 1 if $_[0] =~ /^Consta +nt/ }; eval { *{$name} = sub { "TEST" } }; # set it back eval { *{$name} = $code; }; # all done return $is_constant; } use Test::More tests => 6; use constant CONSTANT1 => 1; use constant CONSTANT2 => [ 'foo', 'bar' ]; sub CONSTANT3 () { '...' } sub NONCONSTANT1 () { $_[0]++ } sub NONCONSTANT2 ($) { "fooey" } sub NONCONSTANT3 { 1; } ok(is_constant("main::CONSTANT1")); ok(is_constant("main::CONSTANT2")); ok(is_constant("main::CONSTANT3")); ok(!is_constant("main::NONCONSTANT1")); ok(!is_constant("main::NONCONSTANT2")); ok(!is_constant("main::NONCONSTANT3"));

It passes my tests despite leaveing me with a not-so-clean feeling.

-sam

Replies are listed 'Best First'.
Re: Re: Is it possible to distinguish contstants from normal subs?
by samtregar (Abbot) on May 19, 2002 at 06:16 UTC
    While working this code into my module (Devel::Profiler) I've found that prototype($name) isn't very reliable. Sometimes it returns the correct prototype of a constant and sometimes it returns undef. On the other hand, prototype($code) always works.

    I find this a bit strange. Maybe this is a bug in Perl (5.6.1)? Or maybe a bug in me? You make the call!

    -sam