LINUX.ORG.RU

А чего оно такое, извините, (1)?$x=1:$x=2 ?

 


0

1

[preamble] Все мы знаем о том, что реклама - не двигатель торговли, а инструмент охамевшего спекулянта, искренне желающего ничего не делать, а только пользоваться результатами чужого труда, поскольку тому, кто работает, как правило некогда думать о том, как бы втюхать произведённое втридорога.

Все мы также знаем о том, что Yandex - лучший друг спекулянтов, потому что основная их статья доходов - это реклама и недостоверная информация в Маркете. Та самая грёбаная реклама, которая делает из интернет большую смердящую навозную кучу с опарышами inside... [/preamble]

Но суть конечно не в этом, а в том, что у Yandex'а задачки интересные. Вот, в частности:

my $x=1;
$x=(1)?$x=1:$x=2;
print $x;

Что будет напечатано?

Ага, напечатано будет «2».

Это весьма неожиданный результат, поскольку та часть тернарного оператора, которая после двоеточия, обычно даже не вычисляется, если условие заведомо истинно.

Если, например, сделать $x=(1)?print "hello\n":print "bye\n", то bye вы уж точно не увидите.

Так почему же в описанном выше случае значением будет всё-таки «2», а не «1»?

★★★★★
Ответ на: комментарий от Ubuntu1210

хз, тернарный оператор действительно должен работать по сокращенной схеме.

nagibator
()
Ответ на: комментарий от dk-

Великий Распространитель Рекламного Говна detected.

Сдохни ;)

DRVTiny ★★★★★
() автор топика

Так почему же в описанном выше случае значением будет всё-таки «2», а не «1»?

$x=(1)?$x=1:$x=2;

Видимо, потому, что операция присваивания «$x=1» возвращает false, там же не «==».

Virtuos86 ★★★★★
()

Так операция присваивания, которая, кстати, даёт цифру «1» (интерпретируется как true в булевом контексте) - её статус и не проверяется никак.

Проблема в том, что в

$x=(1)?$x=1:$x=2;
- второй частью тернарного оператора является не $x=2, а $x.

Такие дела :)

Чтобы получить верный результат нужно заключить $x=2 в скобки.

DRVTiny ★★★★★
() автор топика
Ответ на: комментарий от anonymous

Извини, светоч, я перл не знаю. Высказал предположение.

Virtuos86 ★★★★★
()
Ответ на: комментарий от DRVTiny
$x=(1)?$x=1:$x=2;

- второй частью тернарного оператора является не $x=2, а $x.

Да ну? И что же здесь тогда играет роль lvalue для присваивания =2?

Раз.

($x=(1)?$x=1:$x)=2;

Два.

$x=((1)?$x=1:$x)=2;

В любом из вариантов нет lvalue.

anonymous
()

недостоверная информация в Маркете

баттхёрт от того, что присланная кетайщина оказалась не с перламутровыми пуговицами детектед

anonymous
()
perl -MO=Deparse -E 'my $x=1; $x=(1)?$x=1:$x=2; print $x;'
BEGIN {
    $^H{'feature_unicode'} = q(1);
    $^H{'feature_say'} = q(1);
    $^H{'feature_state'} = q(1);
    $^H{'feature_switch'} = q(1);
}
my $x = 1;
$x = ($x = 1) = 2;
print $x;
-e syntax OK
Olegymous ★★★
()

Это весьма неожиданный результат

Только для тех кто постоянно говорит о своей илитарности и плохо знает Perl.

outtaspace ★★★
()
Ответ на: комментарий от DRVTiny

Просто было интересно, кто первым догадается

Догадываться надо только тем, кто читал верблюжью книгу по диагонали и в пьяном виде. Подобное поведение документировано и разобрано. Ну а кто пытается писать на языке, которого не знает, ну так что ж, «мамы всякие нужны, мамы всякие важны» и профессия младшего помощника заместителя дворника — тоже профессия.

redgremlin ★★★★★
()
Ответ на: комментарий от anonymous

баттхёрт от того, что присланная кетайщина оказалась не с перламутровыми пуговицами детектед

В Маркете представлены только те магазины, которые отбашляли Яндексу за сексуальные услуги, стоимость этих «услуг» по определению включена в любой товар, купленный в таком магазине. В этом нет криминала никакого, но по факту я находил цены и в полтора раза меньше «минимума» на Маркете. Плюс к тому магазины в Маркете не проходят никаких проверок - даже если пользователи кричат «долой мошенников», магазин останется в маркете, ибо деньги для тындекса важнее репутации.

DRVTiny ★★★★★
() автор топика
Последнее исправление: DRVTiny (всего исправлений: 1)
Ответ на: комментарий от anonymous

На самом деле какая-то компиляция двух примров из верблюда:

$con ? $a : $b = 2

+
Пример с приоритетами

anonymous
()
Ответ на: комментарий от DRVTiny

Да, за маркет нужно башлять, ну и что? В стоимость товара много чего включено, и маркет яндекса тут играет далеко не первую роль. Да, можно найти конторы, которые не публикуются на маркете с более дешевыми ценами.

Касаемо проверок, это не так просто сделать. Есть отзывы, и по ним вполне можно составить впечатление как о товаре, так и о магазине. А если сомневаешься, так еще и пробить в гугле контору на предмет отзывов, не вошедших в маркет.

Да, бабло зачастую является определяюшим фактором, но самому то тоже дурачком быть не нужно. И это не так сложно сегодня пробить кого-то и не нарваться на мошенников.

anonymous
()

Да. Люблю таких дядь, задающих такие задачи. Что отличает норм кодера от г. кодера? То что он так не будет писать:

1. Двойное присваивание одной и той же переменной. Нормальный прогер сразу пишет: $x = (1) ? 1 : 2

2. Другой пример. Нормальный кодер знает, что код расширяется и вместо $x = (1) ? $y = 1 : $y = 2 напишет что-то подобное ниже и добавит объяснения:

if (1) {
  # set default value
  $x = $y = 1;
} else {
  # set when test not passed
  $x = $y = 2;
}
Т.о. пример яндекса это реальный случай, уверен, был написан недалеким человеком из отдела тестирования.

gh0stwizard ★★★★★
()

Вот еще распространенная ошибка. Исправьте код, чтобы он заработал.

sub test {
  @_ ? (1,2,3) : 0
}

my @data = test() or die "expected error";

gh0stwizard ★★★★★
()
Последнее исправление: gh0stwizard (всего исправлений: 1)
Ответ на: комментарий от gh0stwizard

Эмм... А в чём ошибка, собственно? Ну возвращает test без аргументов в контексте списка один элемент со значением «0» - может, так программистом и было задумано, просто ему было лень обособлять нолик скобками явным образом.

Вообще по-хорошему нужно проверять, в каком контексте находишься и возвращать значения соответственно:

sub test {
 return wantarray?
          @_ ? (1,2,3) : ()
                 :
          @_ ? shift : 0
}
DRVTiny ★★★★★
() автор топика
Последнее исправление: DRVTiny (всего исправлений: 1)
Ответ на: комментарий от anonymous

Да, бабло зачастую является определяюшим фактором, но самому то тоже дурачком быть не нужно.

Для того, чтобы не быть дурачком, нужно иметь золотые руки и уметь сделать собственными руками половину того, что другие купят у спекулянтов 10-го уровня в башляющем тындексу гамазине.

К сожалению, в этом отношении я дурачок. Хотя из того, что мне постоянно нужно - обслуживать и чинить велосипед, - я в основном уже всё делаю сам и плачу веломастерам очень редко за те операции, которые за неимением оборудования и опыта соотв. не умею выполнять самостоятельно.

DRVTiny ★★★★★
() автор топика
Ответ на: комментарий от Deleted

В том-то и дело, что там нет ошибки. Если программист так и задумал, то поведение вполне нормальное, ничего экстраординарного нет.

Хотя конечно использование конструкции «or die» намекает на то, что программист так не задумывал: функция test никогда не возращает того, что в булевом контексте было бы «ложью», поэтому никакого die никогда и не будет.

DRVTiny ★★★★★
() автор топика
Ответ на: комментарий от anonymous

Смысл был в том, чтобы сказать, что я дурак?

Предлагаю встретиться и сказать мне это в лицо - для прокачки социальных и прочих скиллов.

DRVTiny ★★★★★
() автор топика
Ответ на: комментарий от anonymous

// разница в приоритетах or and и || &&

anonymous
()
Ответ на: комментарий от DRVTiny

То есть ты просто платишь временем за то, что можно заплатить деньгами? Ну такая себе идея, время не заработаешь, а вот деньги - можно.

Dantix ★★
()
Ответ на: комментарий от anonymous

Да вообще круто, тогда test будет вычисляться в скалярном контексте.

А по логике, он и должен возващать список, а не скаляр.

DRVTiny ★★★★★
() автор топика
Ответ на: комментарий от anonymous

...но и не первый раз втречаться очно приходится ;)

DRVTiny ★★★★★
() автор топика
Ответ на: комментарий от Dantix

То есть ты просто платишь временем за то, что можно заплатить деньгами?

А деньги зарабатываются не за какое-то время разве? Ну и да, у меня есть свободное от зарабатывания денег время, когда можно систему открутить-прикрутить, втулку разобрать или ещё что. Меня не парит - для чего ещё нужно свободное время.

DRVTiny ★★★★★
() автор топика

Это детектор принадлежности к чему-то, прокуроры говорят «дело возбУждено», моряки ходят, а не плавают, собаки под хвост смотрят. Программисты пишут ненужную х..ту типа $x=(1)?$x=1:$x=2; или играются с j++ и ++j. Как пользоваться этой фигнёй постоянно вылетает из башки, они вспоминают сначала навыки онанизма, потом как эта хрень работает, потом приходит гордость принадлежности к нечто.

ilovewindows ★★★★★
()
Ответ на: комментарий от anonymous

Однострочник:

sub test { my $i=0; print ">>",wantarray(),"<<\n"; wantarray? @_ ? map {++$i.") ".$_} @_ : () : 0 }; my @data = test(1) or die "expected error"; print join("\n",@data,"")

DRVTiny ★★★★★
() автор топика
Ответ на: комментарий от DRVTiny

А в чём ошибка, собственно?

Ошибка в том, что функция может возвращать список, когда отработала корректно или не возвращать ничего. Тут два решения:

  • Меняем or на ||. Но это костыль, т.к. поведение or и || в контексте применения вместе с die должно быть идеинтичным.
  • Меняем 0 на (), либо на return;

Использовать wantarray в данном случае нет необходимости, т.к. функция всегда возвращает список.

Заблуждение, что return 0; в контексте массива равносильно скалярному контексту:

my @data = 0 or die "WRONG";
my $rv = 0 or die "GOOD";
my @data = () or die "GOOD";

gh0stwizard ★★★★★
()
Последнее исправление: gh0stwizard (всего исправлений: 1)
Ответ на: комментарий от ilovewindows

У современных программистов всё больше принято самовыражение через ООП, где декларации занимают в 20 раз больше, чем собственно продуктивный код.

Но в общем да, нельзя не согласиться с тем, что подобные извращения ничего хорошего о программисте точно не говорят.

Мало того, когда в Яндекс гордо заявляют, что у них всё на Perl 5 и переход на Perl 6 им не грозит в ближайшем будущем, выставляя это чуть ли не как принципиальную позицию - меня это слегка смешит: сначала они понаписали гору кода, невозбранно использующего всякие «фишки» из разряда «Perl для извращенцев», а теперь не смогут его перенести не то, что на другой язык программирования, но даже на следующую версию того же самого языка!

А ведь Perl вполне позволяет писать и в нормальном переносимом стиле, и никто ещё не доказал, что это как-то медленнее работает. Просто это «как-то не круто» и заставляет больше печатать на клавиатуре - только и всего. Не позволяет глубоко прочувствовать свою «илитарность» в общем.

DRVTiny ★★★★★
() автор топика
Ответ на: комментарий от gh0stwizard

Использовать wantarray в данном случае нет необходимости, т.к. функция всегда возвращает список.

Ага, но в скалярном контексте этот список всё равно будет отправлен в /dev/null, а в реальности мы получим количество элементов того, что даже родиться толком не успело :)

DRVTiny ★★★★★
() автор топика
Ответ на: комментарий от DRVTiny

Тебе смешно, а задача взята из реального кода на CPAN.

gh0stwizard ★★★★★
()
Ответ на: комментарий от Sahas

Угу, как говнокод на С — так это говнокодера надо убивать, а как говнокод на перле — так это потому что перл говно? Молодец, на экзамене по двоемыслию получишь 5.

redgremlin ★★★★★
()
Ответ на: комментарий от redgremlin

на С в основном нормально пишут. А вот какую программу на перле не возьми - всё какие-то непонятные закорючки...

Sahas ★★★★☆
()
Ответ на: комментарий от Sahas

А вот какую программу на перле не возьми - всё какие-то непонятные закорючки...

Был я тут на НГ в Армении. Там куда ни посмотри - всё какие-то непонятные закорючки. Надо им язык поменять. А то говорят и пишут на неправильном языке, а надо на русском.

DRVTiny ★★★★★
() автор топика
Последнее исправление: DRVTiny (всего исправлений: 1)
Ответ на: комментарий от Sahas

С -Wall, -Werror не скомпилится, поэтому можно не убивать =)

DELIRIUM ☆☆☆☆☆
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.