Как правильно определить анонимный скаляр ref в Perl?Как определить анонимный скаляр в Perl?
my $scalar_ref = ?;
my $array_ref = [];
my $hash_ref = {};
Как правильно определить анонимный скаляр ref в Perl?Как определить анонимный скаляр в Perl?
my $scalar_ref = ?;
my $array_ref = [];
my $hash_ref = {};
Обычно вы просто объявлять и не инициализировать его.
my $foo; # will be undef.
Вы должны учитывать, что пустой хэш-реффикты и пустой массив refs указывают на структуру данных, которая имеет представление. Оба они, когда разыменовываются, дают вам пустой список.
perldata говорит (курсив мой):
Есть на самом деле две разновидности нулевых строк (иногда называют как «пустые» строки), определенный один и не определен один. Определенная версия - это всего лишь строка с нулевой длиной, например «". Неопределенная версия - это значение, указывающее, что для чего-либо не существует реального значения, например, когда произошла ошибка или в конце файла, или когда вы ссылаетесь на неинициализированную переменную или элемент массива или хэша. Хотя в ранних версиях Perl неопределенный скаляр мог быть определен при первом использовании в месте, ожидающем определенного значения, это больше не происходит, за исключением редких случаев автовивитации, как описано в perlref. Вы можете использовать определенный() оператор, чтобы определить, определено ли скалярное значение (это не имеет значения для массивов или хэшей), и для оператора undef() для получения неопределенного значения.
Так пустой скалярная (который на самом деле не сказать) будет undef
. Если вы хотите, чтобы это была ссылка, сделайте ее одной.
use strict;
use warnings;
use Data::Printer;
my $scalar_ref = \undef;
my $scalar = $$scalar_ref;
p $scalar_ref;
p $scalar;
Этот выход будет:
\ undef
undef
Однако as ikegami pointed out, он будет доступен только для чтения, потому что это не является переменной. LeoNerd provides a better approach for this in his answer.
Во всяком случае, моя точка, пустой хэш ссылок и пустой массив ссылок, когда разыменовываются оба содержат пустой список ()
. И это не undef
но ничего. Но нет ничего как скалярное значение, потому что все, что есть не ничего - скалярное значение.
my $a = [];
say ref $r; # ARRAY
say scalar @$r; # 0
say "'@$r'"; # ''
Так что нет никакого реального способа инициализации с ничего. Вы можете только не инициализировать. Но Moose превратит его в undef
в любом случае.
Что вы можете сделать, это сделать его Возможно скаляр ref.
use strict;
use warnings;
use Data::Printer;
{
package Foo;
use Moose;
has bar => (
is => 'rw',
isa => 'Maybe[ScalarRef]',
predicate => 'has_bar'
);
}
my $foo = Foo->new;
p $foo->has_bar;
p $foo;
say $foo->bar;
Выход:
""
Foo {
Parents Moose::Object
public methods (3) : bar, has_bar, meta
private methods (0)
internals: {}
}
Use of uninitialized value in say at scratch.pl line 268.
predicate
дает значение, которое не верно (пустая строка ""
). undef
также не соответствует действительности. Люди, которые заставили Муса решили пойти с этим, но это действительно не имеет значения.
Возможно, что вы хотите, не имеет значения по умолчанию, а просто сделайте его ScalarRef
a required
.
Обратите внимание, что perlref ничего об инициализации пустого скалярного рефа либо не говорит.
Это определяет пустой скаляр, который я могу создать ссылку, но как я могу определить его анонимно? – tjwrona1992
Зачем вам это нужно? Скалярный ref является скаляром. – Sobrique
Я создаю объект 'Moose', который имеет атрибут типа« ScalarRef », и я хочу определить для него значение по умолчанию. – tjwrona1992
Я не совсем уверен, почему вам нужно, но я хотел бы предложить:
my $ref = \undef;
print ref $ref;
Или возможно:
my $ref = \0;
Спасибо, что работает :) – tjwrona1992
Создают ссылки на скаляры только для чтения. – ikegami
Если вы хотите ссылку на какой-то изменяемым хранения, нет особенно аккуратный прямой синтаксис для него. О лучшем случае вы можете управлять является
my $var;
my $sref = \$var;
Или аккуратнее
my $sref = \my $var;
Или, если вы не хотите, сама переменная находиться в области видимости больше, вы можете использовать делать блок:
my $sref = do { \my $tmp };
На этом этапе вы можете пройти $sref
по значению, а любые мутации к скаляру, на которые ссылаются, будут видны другими.
Этот метод, конечно, работает так же хорошо для массива или хеш-ссылок, только что есть аккуратнее синтаксис делать это с []
и {}
:
my $aref = do { \my @tmp }; ## same as my $aref = [];
my $href = do { \my %tmp }; ## same as my $href = {};
Вы можете инициализировать его до нуля: Perl -E «$ а = \ 0; скажем $ a; say $$ a 'so '$ a' теперь является скалярной ссылкой, а содержимое ссылки является скаляром 0. –
См. мой обновленный rant. – simbabque