in reply to Re^2: Is "ref($class) || $class" a bad thing?
in thread Is "ref($class) || $class" a bad thing?

Seems like it'd be less work to write:

sub new { croak "new() called as a function, not a method\n" unless @_; bless {}, shift; }

If you really want to be paranoid, though, you should make something similar a precondition of all of your methods. (For convenience sake of everyone else, though, please use [CPAN://Scalar::Util]::blessed(). Also, you ought to call isa() directly, not through UNIVERSAL::, in case someone overrides it.

Replies are listed 'Best First'.
Re^4: Is "ref($class) || $class" a bad thing?
by stvn (Monsignor) on Jul 13, 2004 at 01:11 UTC
    Seems like it'd be less work to write:
    sub new {     croak "new() called as a function, not a method\n" unless @_;     bless {}, shift; }

    As dragonchild already pointed out, this would not handle Foo::new({}), nor would it handle Foo::new("Data::Dumper"). Both are things are equally as stupid for a user to do, but a new user may not realize the method/function difference, the real question is whether that is my reponsibility or not.

    If you really want to be paranoid, though, you should make something similar a precondition of all of your methods.

    I assume you mean to check $self, that is true, but even I think that would a little much.

    Also, you ought to call isa() directly, not through UNIVERSAL::, in case someone overrides it.

    That too would not work for Foo::new({}) or other such insanity.

    I am really just trying to find something in between totally over-the-top paranoid, and you-break-it-you-buy-it-an-I-dont-care. And I am still looking as I think the example I gave above it probably too much.

    -stvn
      #!/usr/bin/perl -w use strict; use Test::More tests => 5; package Foo; sub new { my $class = shift; return unless eval { $class->isa( __PACKAGE__ ) }; bless {}, $class; } sub is_object { 1 }; package Bar; @Bar::ISA = 'Foo'; package main; sub is_object { 0 }; my $foo = Foo->new(); isa_ok( $foo, 'Foo' ); my $bar = Bar->new(); isa_ok( $bar, 'Bar' ); ok( $foo->is_object(), '$foo is an object' ); ok( $bar->is_object(), '$bar is an object' ); my $hash = Foo::new( {} ); is( $hash, undef, 'Foo::new() should not bless a reference passed in' +);
Re^4: Is "ref($class) || $class" a bad thing?
by adrianh (Chancellor) on Jul 17, 2004 at 14:31 UTC

    I'm surprised nobody has mentioned called_as_method from Devel::Caller.

    use Devel::Caller qw( called_as_method ); sub new { croak "must call new as method" unless called_as_method(0); ... };
      I'd consider that "a bit too much navel inspection". It breaks code I write that looks like this:
      my $destiny = $someobject->can("somemethod"); @_ = ($someobject, @args); goto &$destiny;
      There shouldn't be any way that this target method should be able to tell that I got there with ->can instead of a true method lookup. So if you write code that breaks that, shame on you.

      -- Randal L. Schwartz, Perl hacker
      Be sure to read my standard disclaimer if this is a reply.

        I'd consider that "a bit too much navel inspection"

        Oh I agree completely (I said I was surprised that nobody had mentioned it - not that it was a good idea :-)

        It breaks code I write that looks like this:

        ++ Good point.