Согласно POD, blessed()
работает только для благословенных ссылок (например, ссылок, переданных на вызов bless()
).
Возвращает undef
для всего остального, включая ссылки на хеш / массив, где ref()
возвращает HASH
/ ARRAY
(и множество других типов, как указано в perldoc ref ). Чтобы получить справочный тип, вы можете, конечно, позвонить Scalar::Util::reftype
.
Что касается того, следует ли использовать один над другим, я думаю, что это в значительной степени зависит от логики.
Если вы только хотите отличить настоящие благословенные ссылки от всего остального, blessed()
предоставляет более краткий способ, чем взятие ref
, а затем проверка того, что значение не соответствует стандартному возвращенные по неподтвержденной ссылке.
my $ref_type = ref($my_ref);
print "USING REF: ";
if ( $ref_type
&& $ref_type ne ref({})
&& $ref_type ne ref([])
&& $ref_type ne "SCALAR"
# Could also use a hash with all allowed values of ref() instead
&& $ref_type !~ /^(CODE|REF|GLOB|...)$) {
print "I am an object of class $ref_type\n";
} else {
print "I'm a reference of type $ref_type\n";
}
# vs...
print "USING SCALAR_UTIL: ";
my $ref_type = blessed($my_ref);
print $ref_type ? "I am an object of class $ref_type\n"
: "I am a reference of type " . reftype($my_ref) . "\n";
Если вам нужны точные различия как между благословенными ссылками, так и с разными ublessed ссылками, то один ref()
вызов является более кратким, чем комбинация blessed
и reftype
.
Один крайний случай, когда существует реальная функциональная разница между двумя подходами, как отмечено в комментариях Эрика Строма, - это когда кто-то создает класс, который соответствует одному из ref()
жестко закодированных значений (например, bless [], 'HASH'
- в этом случае они либо тупые, либо слишком умные вдвое).
my $sssft = bless [], 'HASH'; # sssft = someone_should_suffer_for_this
ref_description_using_ref($sssft);
ref_description_using_scalar_util($sssft);
# OUTPUT:
USING REF: I'm a reference of type HASH
USING SCALAR_UTIL: I am an object of class HASH
ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: На основании документации не должно быть никакой разницы между этими двумя, когда аргумент является ссылкой, благословленной в классе (например, он возвращает имя класса). Но я не проверял источник "Scalar :: Util" для подтверждения.