in reply to Is "ref $date eq 'ARRAY'" wrong?

I'm still relatively new to perl, so forgive the 'bad design' that everyone is talking about... but...

I wrote an object that had a hash ref as part of the object properties (set via the $obj=new CLASS or $obj->Req_Trace(\%mytrace) method)
* In order to ensure that I really had a hash (and not something else, 'case user made a mistake), I used something similar to this...

my $self = shift; my %req = (); if (ref($self->Req_Trace()) eq "HASH") { %req = %{$self->Req_Trace()}; }

Is this a case where using ref within an 'if' statement makes it ok?

Is using @ISA supposed to be used here? If so, how?

What don't I understand?

Could someone explain it to me? (assume that I am not knowledgable about much).

Thanks.

Replies are listed 'Best First'.
Re: Re: Is "ref $date eq 'ARRAY'" wrong?
by runrig (Abbot) on Dec 20, 2003 at 16:53 UTC

    It looks like you are using Req_Trace as a setter/getter, and that Req_Trace should only be set to a hash ref if set at all. In the above code, it looks like you are checking to see if its a hash ref after it's already been set, which IMO is the wrong place to be doing that. You should check to see if its a hash ref while it is being set, and in the above code, you would/may only need to check to see if it is set at all.

    That being said, to check to see if Req_Trace is passed a hash reference, some here would say to use UNIVERSAL::isa($rt_arg, 'HASH'), and some would say ref($rt_arg) eq 'HASH' is fine. Either way is 'broken' in one way or another:
    my $aref = [ 1..5 ]; bless $aref, 'HASH'; # An array ref now thinks it's a hash ref print "aref is a HASH\n" if ref($aref) eq 'HASH'; print "aref is a HASH\n" if UNIVERSAL::isa($aref, 'HASH'); my $href = { 0..9 }; # This is ok print "href is a hash\n" if ref($href) eq 'HASH'; bless $href, 'Some::Package'; # This may not be ok print "href is not a hash\n" unless ref($href) eq 'HASH';
    IMO, if you don't want to accept a blessed object which happens to be implemented as a hash ref (which is fine IMO), then ref is fine (I just want a hash ref, I don't want no damn stinkin' objects! :-) (update: oops, but it also accepts an object that thinks its a hash :). If you want to make absolutely sure that the argument passed is a hash reference, blessed or not, then you use Scalar::Util::reftype(). If you think people deserve what they get if they bless a non-hash reference into a 'HASH' package (I would lean this way also), then UNIVERSAL::isa is fine too.
      Thanks!

      And yeah, I know I should be checking if the has ref is a hash ref when it is being set, but I was new to OO and I used the examples in the camel book. In there, there is a nice example of creating methods on the fly.

      In retrospect, I would not have done it this way.

      So my way works only because this is the only place i actually use the hash, but at some future date if someone else adds to my module, it could possibly blow up.

      I'll fix it, I'll fix it... she whines...