in reply to How to differentiate hash reference and object reference?

I have to say that I wonder about validation code like this. Whats the point? You are checking the type to throw an error, but what will happen if you try to use the object without doing these checks? Remarkably, in almost every way the exact same thing will happen (under strict anyway), ie, the interpreter will throw an errror.

So just let the interpreter throw the error.

Now I can hear the peanut gallery saying "yeah but what happens if they pass in an object that is blessed into a package that has the methods im concerned about?" My answer would be, you mean you know in advance that this would be wrong? What happens if they decide to reimplement the interface in a different class structure and decide to use that?

IE, most of this type of validation just removes the flexibility of the consumer, and adds very little or nothing to the robustness of your code.

I will agree there are cases where doing checks like these properly is vital, but IMO that is usally confined to cases where you have specific handlers for different input types, not simply screen for a valid type.

Ultimately if you _do_ want to do checks like these then you should look into using Scalar::Util.

---
$world=~s/war/peace/g

  • Comment on Re: How to differentiate hash reference and object reference?

Replies are listed 'Best First'.
Re^2: How to differentiate hash reference and object reference?
by tphyahoo (Vicar) on Aug 31, 2005 at 14:24 UTC
    The thing is, I want to be able to control my error messages. Right now, I have
    #The error I get: #C:\thomasdata\experiments>perl unblessedWantBetterError.t #Can't call method "isa" on unblessed reference at unblessedWantBetter +Error.t lin #e 10.
    It is an error message, but it comes from the compiler, not from me. My main problem with it is isn't so much the wording, but the fact that it doesn't even say which argument caused the problem. Maybe params validate solves that?

    That said, I am overall not currently happy with how I'm going about params checking. I will have a look at Params::Validate like diotalevi said, and maybe give my whole way of doing this a rethink.

      My main problem with it is isn't so much the wording, but the fact that it doesn't even say which argument caused the problem.

      Sure it does. the message says

      Can't call method "isa" on unblessed reference at unblessedWantBetterError.t line 10.

      Which tells us that on line 10 some $var is being used as an object in a method call and the content of $var is not actually an object. When we look at line 10 we see

      die "not a foo" unless $obj->isa('foo'); #the error I want

      which tells us that the $var in question is called $obj.

      Now presumably you are doing this because later on you have code that does something like

      $obj->do_something($useful);

      But what do you gain? In this situation you would see the same error you are now just on the actual line where the actual code is being used, and not on some validation code.

      So IMO you gain nothing but code complexity and you tie the hands of your codes consumers because they can't drop in a different object with a compatible interface. So IOW, you have made your code less usable and robust than more.

      ---
      $world=~s/war/peace/g

        Not sure I agree if this is in the context of argument checking -- in which case it should be used with croak (from Carp) and not die.

        If the OP is writing a subroutine that takes an argument and then uses that argument to call a method defined for objects of type 'foo', then not checking the parameter means potentially dying with an error message pointing to the line in the OP's subroutine, not pointing to where the subroutine was called with an invalid argument:

        sub wibble { my ($self, $obj) = @_; croak "Argument to wibble must be a 'foo' object" if ! ( blessed $obj and $obj->isa('foo') ); if ( $obj->wobble() eq 'spoon' ) { # handle spoon } }

        Or, as diotalevi said, use Params::Validate.

        -xdg

        Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.