Re: Overloading ref() just like ->isa and ->can?
by dragonchild (Archbishop) on Apr 18, 2006 at 16:16 UTC
|
Actually, the best practices recommendation should be:
eval {
local $SIG{__DIE__};
$obj->isa( ... );
}
Otherwise, you will trigger all SIGDIE handlers and, not surprisingly, Test::More has one.
My criteria for good software:
- Does it work?
- Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
| [reply] [d/l] |
|
|
Otherwise, you will trigger all SIGDIE handlers and, not surprisingly, Test::More has one.
Test::Builder, actually. To whit:
$SIG{__DIE__} = sub {
# We don't want to muck with death in an eval, but $^S isn't
# totally reliable. 5.005_03 and 5.6.1 both do the wrong thing
# with it. Instead, we use caller. This also means it runs under
# 5.004!
my $in_eval = 0;
for( my $stack = 1; my $sub = (CORE::caller($stack))[3]; $stack+
++ ) {
$in_eval = 1 if $sub =~ /^\(eval\)/;
}
$Test_Died = 1 unless $in_eval;
};
I'm afraid that eval{} users have to be allowed the ease-of-coding advantage over die-handlers. The whole purpose of eval is to catch an exception; you shouldn't have to go through additional hoops to protect against an exception. Yes, there's a perl design botch, but eval{} shouldn't have to suffer for it. (As far as I know, $^S is working in newer perls, which should make things a little easier.) | [reply] [d/l] |
Re: Overloading ref() just like ->isa and ->can?
by chromatic (Archbishop) on Apr 18, 2006 at 18:30 UTC
|
I find the best approach is to find the person who sneaked it into the code and administer friendly beatings until it disappears. ref breaks polymorphism. That's a no-no.
| [reply] |
|
|
You mean like HTML::Template?
My criteria for good software:
- Does it work?
- Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
| [reply] |
|
|
| [reply] |
Re: Overloading ref() just like ->isa and ->can?
by Roy Johnson (Monsignor) on Apr 18, 2006 at 16:04 UTC
|
| [reply] [d/l] [select] |
Re: Overloading ref() just like ->isa and ->can?
by creamygoodness (Curate) on Apr 18, 2006 at 16:21 UTC
|
What are you hoping to get out of ref() and what is it giving you now when you feed it your faker-objects?
Incidentally, if Scalar::Util's blessed() is available, $result = blessed($maybe_obj) and $maybe_obj->isa( ... ); might be faster than eval { $result->isa( ... ) };.
Rate eval2 blessed1 eval1 blessed2
eval2 6.80/s -- -57% -61% -76%
blessed1 15.9/s 134% -- -9% -43%
eval1 17.4/s 156% 10% -- -38%
blessed2 28.0/s 313% 76% 61% --
Here's the test script:
| [reply] [d/l] [select] |
|
|
When foreign code uses ref() on a proxy object, it sees the proxy object's class, not the class that the object is proxying for. The proxy object would need the foriegn code to be told that the proxy object is of the proxied class. That is, ref( $obj ) or its equivalent that I'm inquiring about would not return $obj's class but the class that $obj is proxying for. This looks like the same problem that UNIVERSAL::isa and UNIVERSAL::isa were created for.
| [reply] [d/l] [select] |
Re: Overloading ref() just like ->isa and ->can - best practice for isa(HASH)?
by imp (Priest) on Aug 22, 2006 at 14:04 UTC
|
What would be the best practice method for determining if something is a hash or array? At times I want to know that the underlying object is a hashref, even if it has been blessed.
e.g.
use strict;
use warnings;
{
package foo;
sub new { bless {}, shift};
}
my $foo = foo->new();
print "ref(foo) = ",ref($foo), "\n";
print "foo is a hash\n" if UNIVERSAL::isa($foo,'HASH');
my $bar = {a => 1};
# The following won't work
# print "bar is a hash\n" if $bar->isa('HASH');
print "bar is a hash\n" if UNIVERSAL::isa($bar,'HASH');
| [reply] [d/l] |
|
|
use B qw( svref_2object SVt_PVHV );
sub is_hash {
my $ref = shift @_;
return ref( $ref )
and svref_2object( $ref ) & SVt_PVHV;
}
If you just want to know whether it supports being treated like a hash, do something akin to a ->can test for hash-ness. If the hash dereference doesn't die, then $ref acts like a hash. sub does_hash {
my $ref = shift @_;
return ref( $ref )
and eval { %$ref; 1 };
}
| [reply] [d/l] [select] |