Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Re: Behaving appropriately based on ref() result

by demerphq (Chancellor)
on Jan 09, 2006 at 09:04 UTC ( [id://521877]=note: print w/replies, xml ) Need Help??


in reply to Behaving appropriately based on ref() result

When i have had to do this its looked much like you have posted. However as others have pointed out you will have issues with using ref() for this task. And unfortunately reftype() isn't a complete solution to the problem as 'Regexp' is unfortunately not treated as a native Perl type but rather as a blessed scalar reference. Thus reftype(qr/./) will return SCALAR not "Regexp".

In Data::Dump::Streamer I provide some utility XS methods that make this job a little easier. Data::Dump::Streamer::reftype() is similar to that provided by Scalar::Util except it returns PL_no (false) instead of undef which means you don't have to bother with a checking if the response is defined. A simple (if reftype($foo) eq 'SCALAR') will not raise a warning.

A second utility function of interest is Data::Dump::Streamer::regex() which in list context returns a list containing the regex pattern (without quoting or '(?:)' wrapper) and the modifiers on the pattern, and in scalar context returns the same as a stringified qr// would. This routine can not be fooled by blessing the qr// or by overloading its stringification logic (which says to me that regex's are native types distinct from normal SCALAR's and that they should receive a unique reftype designation)

So the logic would look something like this:

use Data::Dump::Streamer qw(reftype regex); my $type=reftype($obj); if ($type eq 'SCALAR' and my $re=regex($obj)) { # Its a regex, $re contains the unquoted pattern } elsif ($type eq 'REF' or $type eq 'SCALAR' or $type eq 'GLOB') { # its something that can be derefed by $$obj } elsif ( $type eq 'HASH' ) # its a hash } elsif ( $type eq 'ARRAY' ) # its an array } elsif ( $type eq 'CODE' ) # its code ref } elsif ( $type eq 'FORMAT' ) # its a format ref } elsif ( $type) { warn "Unhandled type: '$type'\n"; } else { # its not a reference at all }

For my uses I never found a dispatch table to be worthwhile. I think the overhead of doing the lookup and dispatch is more than doing the string comparisons in this case. For a larger dispatch table it might be worth while tho. You'd have to benchmark to see.

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

Replies are listed 'Best First'.
Re^2: Behaving appropriately based on ref() result
by suaveant (Parson) on Jan 09, 2006 at 15:00 UTC
    Of course, the overhead difference is hardly such that your typical Perl program would suffer, but certainly if you are being speed conscious. Especially since you can arrange your constructs so that the most common options come first.

    I often prefer dispatch for the ease of adding new items.

                    - Ant
                    - Some of my best work - (1 2 3)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://521877]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others perusing the Monastery: (5)
As of 2024-04-19 13:49 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found