2009-10-29 3 views
3

Я пробовал этот пример в Perl. Может кто-нибудь объяснить, почему это правда?Почему в этом примере Perl задано значение sdf true?

if (defined sdf) { print "true"; } 

Отпечатано true.

sdf может быть любым именем.

Кроме того, если функция sdf определена и она возвращает 0, то она ничего не печатает.

print (sdf); не печатает SDF строку, но

if (sdf eq "sdf") 
{ 
print "true"; 
} 

печатает правда.

Связанный вопрос остается, если sdf является строкой. Что не печатается печатью?

+0

@Aftershock: Я обновил свой ответ, чтобы ответить на последний вопрос, который вы подняли. –

ответ

10

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}" 

См Strictly speaking about use 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(), возвращая числовой эквивалент по умолчанию $_, обработанного как восьмеричное число.

Исправлено: (спасибо @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. 

Если bareword подается в print в косвенном слот объекта, он берется в качестве дескриптора файла для печати на. Поскольку никаких других аргументов не задано, print по умолчанию печатает $_ для дескриптора файла sdf. Поскольку sdf не был открыт, он терпит неудачу. Если вы запустите это без предупреждений, вы не увидите никакого вывода. Примечание:

 
E:\Home> perl -MO=Deparse -e "print sdf" 
print 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, если они состоят только из символов «слово», удаление дескриптора интерпретации первого аргумента.

Все эти примеры показывают, что использование простых слов приводит к множеству сюрпризов. Чтобы избежать таких случаев, вы должны use strict.

3

defined возвращает true, если выражение имеет значение, отличное от неопределенного значения.

+0

Имеет ли это значение? Печать sdf ничего не показывает ... – Aftershock

+2

@Sinan Ünür: потому что печать принимает косвенный объект, а не потому, что вызов печати предоставляет контекст списка. – ysth

+0

@ysth отметил. Я отредактировал свой ответ, чтобы отразить вашу коррекцию. –

4

пример не является специальным:

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 что и defined проверяет наличие.

Вы можете проверить эту статью на истину в Perl: What is Truth?

+1

Ваш последний пример, '8', отличается от остальных критическим способом. –

+2

@ Синан: Да, это номер. Объяснение того, что 'sdf' является делом, полезно, но основное внимание было уделено тому, что в sdf не было ничего волшебного. – Telemachus

+0

@ Синан: спасибо за это. Я всегда считал, что пустая строка * была * undefined. Это моя ошибка, и я исправлю это. – Telemachus

5

Это «bareword». Если это разрешено, оно имеет значение "sdf" и поэтому не определено.

+0

Фактически, '0' является' false', а 'defined'. Проверьте это: 'perl -e 'if (defined 0) {print" True \ n "};'' – Telemachus

+0

Извините, вы абсолютно правы. :-) Теперь исправлено. – Tim

0

Определенная функция возвращает значение true, если значение, переданное в аргументе, не определено. Это полезно для выделения переменной, содержащей 0 или «", из переменной, которая только что подмигивала.