Почему определенный sdf возвращает true в этом примере Perl?
Вопрос
Я попробовал этот пример на Perl. Может кто-нибудь объяснить, почему это правда?
if (defined sdf) { print "true"; }
Он печатает true
.
sdf может быть любым именем.
Кроме того, если определена функция sdf и она возвращает 0, то она ничего не печатает.
print (sdf);
не печатает строку sdf, но
if (sdf eq "sdf")
{
print "true";
}
печатает true.
Соответствующий вопрос остается, если sdf является строкой. Что это не напечатано печатью?
Решение
sdf
- это bareword . р>
perl -Mstrict -e "print qq{defined\n} if defined sdf"
Bareword "sdf" not allowed while "strict subs" in use at -e line 1. Execution of -e aborted due to compilation errors.
Для большего удовольствия попробуйте
perl -Mstrict -e "print sdf => qq{\n}"
См. Строго говоря, об строгом использовании :
Аспект sub в использовании strict запрещает интерпретацию `` голых слов '' как текстовых строк. По умолчанию идентификатор Perl (последовательность букв, цифр и символов подчеркивания, не начинающаяся с цифры, если она не является полностью числовой), которая не является встроенным ключевым словом или ранее увиденным определением подпрограммы, обрабатывается как текстовая строка в кавычках: р>
@daynames = (sun, mon, tue, wed, thu, fri, sat);
Однако это считается опасной практикой, потому что это может привести к неясным ошибкам:
@monthnames = (jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec);
Можете ли вы обнаружить ошибку? Да, 10-я запись - это не строка 'oct', а скорее вызов встроенной функции
oct ()
, возвращающий числовой эквивалент значения по умолчанию$ _
трактуется как восьмеричное число. Р>
Исправлено: (спасибо @ysth)
E:\Home> perl -we "print sdf" Unquoted string "sdf" may clash with future reserved word at -e line 1. Name "main::sdf" used only once: possible typo at -e line 1. print() on unopened filehandle sdf at -e line 1.
Если голое слово передается в print
в слоте косвенного объекта, оно берется в качестве дескриптора файла для печати. Поскольку другие аргументы не передаются, print
по умолчанию печатает $ _
для дескриптора файла sdf
. Поскольку sdf
не был открыт, произойдет сбой. Если вы запустите это без предупреждений, вы не увидите никакого вывода. Обратите внимание:
E:\Home> perl -MO=Deparse -e "print sdf" print sdf
sdf
- это bareword . р>perl -Mstrict -e "print qq{defined\n} if defined sdf"
Bareword "sdf" not allowed while "strict subs" in use at -e line 1. Execution of -e aborted due to compilation errors.Для большего удовольствия попробуйте
perl -Mstrict -e "print sdf => qq{\n}"
См. Строго говоря, об строгом использовании :
Аспект sub в использовании strict запрещает интерпретацию `` голых слов '' как текстовых строк. По умолчанию идентификатор Perl (последовательность букв, цифр и символов подчеркивания, не начинающаяся с цифры, если она не является полностью числовой), которая не является встроенным ключевым словом или ранее увиденным определением подпрограммы, обрабатывается как текстовая строка в кавычках: р>
@daynames = (sun, mon, tue, wed, thu, fri, sat);
Однако это считается опасной практикой, потому что это может привести к неясным ошибкам:
@monthnames = (jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec);
Можете ли вы обнаружить ошибку? Да, 10-я запись - это не строка 'oct', а скорее вызов встроенной функции
oct ()
, возвращающий числовой эквивалент значения по умолчанию$ _
трактуется как восьмеричное число. Р>Исправлено: (спасибо @ysth)
E:\Home> perl -we "print sdf" Unquoted string "sdf" may clash with future reserved word at -e line 1. Name "main::sdf" used only once: possible typo at -e line 1. print() on unopened filehandle sdf at -e line 1.Если голое слово передается в
$ _
для дескриптора файлаsdf
. Посколькуsdf
не был открыт, произойдет сбой. Если вы запустите это без предупреждений, вы не увидите никакого вывода. Обратите внимание:E:\Home> perl -e "print asdfg, sadjkfsh" No comma allowed after filehandle at -e line 1.в качестве подтверждения этого наблюдения. Обратите внимание:
E:\Home> perl -e "print asdfg => sadjkfsh" asdfgsadjkfsh<*>Последний печатает обе строки, потому что
= >
автоматически заключает в кавычки строки в LHS, если они состоят исключительно из символов «слово», удаляя интерпретацию дескриптора файла первого аргумента.Все эти примеры показывают, что использование голых слов приводит к множеству сюрпризов. Вы должны
;использовать строгий
, чтобы избежать таких случаев.
в качестве подтверждения этого наблюдения. Обратите внимание:
<*> <*> Последний печатает обе строки, потому что = >
автоматически заключает в кавычки строки в LHS, если они состоят исключительно из символов «слово», удаляя интерпретацию дескриптора файла первого аргумента.
Все эти примеры показывают, что использование голых слов приводит к множеству сюрпризов. Вы должны использовать строгий
, чтобы избежать таких случаев.
Другие советы
Это bareword " ;. Если это разрешено, оно имеет значение " sdf "
и поэтому не является неопределенным.
Пример не особенный:
telemachus ~ $ perl -e 'if (defined sdf) { print "True\n" };'
True
telemachus ~ $ perl -e 'if (defined abc) { print "True\n" };'
True
telemachus ~ $ perl -e 'if (defined ccc) { print "True\n" };'
True
telemachus ~ $ perl -e 'if (defined 8) { print "True\n" };'
True
Ни один из них не эквивалентен undef
, который это то, что <код> определено проверяет.
Возможно, вы захотите проверить эту статью об истине в Perl: Что такое истина?
<код> определено возвращает значение true, если выражение имеет значение, отличное от неопределенного значения.
определенная функция возвращает true, если значение, переданное в аргументе, не определено. Это полезно при различении переменной, содержащей 0 или "quot;" из переменной, которая только что подмигнула в существование.