LINUX.ORG.RU

Как отличить аргумент-константу от аргумента-переменной?

 byref, byval, ,


0

3

How on the Earth...

Давайте, не мудрствуя лукаво, рассмотрим пример кода, в котором немного не достаёт функционала одной проверки:

sub f {
  my $refStr=\$_[0];
  return if passed_as_constant($_[0]) and !defined(wantarray);
  substr(${$refStr}, 0, 1)='D';
# return the copy of the string if it was passed
# to the function as constant aka "literally" or if copying was explicitly requested by the left-side context
  (passed_as_constant($_[0]) or defined(wantarray)) and return ${$refStr};
}
# Argument was passed literally and function called without left-side context - we may simply "do nothing"
f('Bingo!');

# Argument was passed literally and left-side context is here. We must return a copy of literal/constant
say my $s=f('Bingo!');

# Here we can modify the $s "in-place"
f(my $s='Bingo!');

Собственно, вопрос: как (on the Earth) реализовать вот это самое passed_as_constant? :)

ОТВЕТ:

use Scalar::Util qw(readonly);
{ no strict 'refs'; *{'main::passed_as_constant'}=\&readonly; }

★★★★★

Последнее исправление: DRVTiny (всего исправлений: 2)

Что ещё за passed_as_constant? Если это было use constant PI => 10, то оно тебе просто не даст с этим так обращаться, как ты это делаешь. А если ты хочешь аналог плюсового:

void my_func(const double &penetration);

,

то в перле языком такого не предусмотрено.

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

Слушай, зачем не читаешь - отвечаешь. Почитай вопрос - ответь. А то как-то нехорошо получается, честное слово.

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

Ты пытаешься заниматься микрооптимизациями в коде на Perl? Зачем?

i-rinat ★★★★★
()
use Scalar::Util qw(readonly);

sub f {
  my $refStr=\$_[0];
  return if readonly($_[0]) and !defined(wantarray);
  substr(${$refStr}, 0, 1)='D';
# return the copy of the string if it was passed
# to the function as constant aka "literally" or if copying was explicitly requested by the left-side context
  (readonly($_[0]) or defined(wantarray)) and return ${$refStr};
}
# Argument was passed literally and function called without left-side context - we may simply "do nothing"
f('Bingo!');

# Argument was passed literally and left-side context is here. We must return a copy of literal/constant
say my $s=f('Bingo!');

# Here we can modify the $s "in-place"
f(my $s='Bingo!');


В Perl не разбираюсь, но вроде работает с 1м и 3м кейсом. Во втором - не работет

P.S. Какой же ваш перл стрёмный

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

Вот так правильно, а то я по сути вслепую впечатывал пример :)

use 5.16.1;
use strict;
use warnings;
use Scalar::Util qw(readonly);

sub f {
  my $refStr=\$_[0];
  return if readonly($_[0]) and !defined(wantarray);
  substr(${$refStr}, 0, 1)='D';
# return the copy of the string if it was passed
# to the function as constant aka "literally" or if copying was explicitly requested by the left-side context
  (readonly($_[0]) or defined(wantarray)) and return ${$refStr};
}
# Argument was passed literally and function called without left-side context - we may simply "do nothing"
f('Bingo!');

# Argument was passed literally and left-side context is here. We must return a copy of literal/constant
say my $s1=f('Bingo!');

# Here we can modify the $s "in-place"
f(my $s2='Bingo!');
say $s2;

Работает как и задумано.

Надо бы ещё через дебаггер пропустить :)

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

Ну так ты на мой вопрос не ответил, так что мы квиты. Мне совершенно неинтересно, что там за константы в Сях, я вообще в ассемблер умею :)

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

Вот запуск с аналогом башового set -x :

$ perl -d:Trace Apps/Perl5/readonly.pl
>> Apps/Perl5/readonly.pl:16: f('Bingo!');
>> Apps/Perl5/readonly.pl:8:   my $refStr=\$_[0];
>> Apps/Perl5/readonly.pl:9:   return if readonly($_[0]) and !defined(wantarray);
>> Apps/Perl5/readonly.pl:19: say my $s1=f('Bingo!');
>> Apps/Perl5/readonly.pl:8:   my $refStr=\$_[0];
>> Apps/Perl5/readonly.pl:9:   return if readonly($_[0]) and !defined(wantarray);
>> Apps/Perl5/readonly.pl:10:   substr(${$refStr}, 0, 1)='D';
>> Apps/Perl5/readonly.pl:10:   substr(${$refStr}, 0, 1)='D';
>> Apps/Perl5/readonly.pl:13:   (readonly($_[0]) or defined(wantarray)) and return ${$refStr};
>> Apps/Perl5/readonly.pl:13:   (readonly($_[0]) or defined(wantarray)) and return ${$refStr};
Dingo!
>> Apps/Perl5/readonly.pl:22: f(my $s2='Bingo!');
>> Apps/Perl5/readonly.pl:8:   my $refStr=\$_[0];
>> Apps/Perl5/readonly.pl:9:   return if readonly($_[0]) and !defined(wantarray);
>> Apps/Perl5/readonly.pl:10:   substr(${$refStr}, 0, 1)='D';
>> Apps/Perl5/readonly.pl:10:   substr(${$refStr}, 0, 1)='D';
>> Apps/Perl5/readonly.pl:13:   (readonly($_[0]) or defined(wantarray)) and return ${$refStr};
>> Apps/Perl5/readonly.pl:24: say $s2;
Dingo!

Вполне ОК, «всё правильно делает».

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

Перестань насиловать труп.

hateyoufeel ★★★★★
()

Слишком умные функции - зло, так как могут скрывать логические ошибки в вызывающем коде

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