ocehb: (Default)
[personal profile] ocehb

# perl -le 'sub a () { my $ret = "scalar A"; $ret->{'a'} = "hash A"; return $ret };
   print a (); print a ()->{'a'};'
scalar A
hash A


удобное, но относительно опасное средство для возвращения параметров.


более интересно (для программистов):


# perl -le 'package Main;
  sub a { my $ret = ""; $ret->{'a'} = "hash A"; return $ret };
  sub b { my $ret = ""; $ret->{'a'} = "hash B"; return $ret };
  package main;
  my $a = Main->a(); my $b = Main->b();
  print "Hash A: ",$a->{'a'};
  print "Hash B: ",$b->{'a'};' 
Hash A: hash B
Hash B: hash B
#


описания данного поведения каk feature не нашел.

Date: 2009-06-25 09:41 am (UTC)
From: [identity profile] lionet.livejournal.com
Hash A: hash B
Hash B: hash B


Фича? Да это диверсия!

Date: 2009-06-25 09:54 am (UTC)
From: [identity profile] lionet.livejournal.com
Ну а я что сказал? По-моему, это синонимы.

Date: 2009-06-25 09:58 am (UTC)
From: [identity profile] what-me.livejournal.com
а где use strict;?

Date: 2009-06-25 10:08 am (UTC)
From: [identity profile] ico.livejournal.com
А так неинтересно! :)

Date: 2009-06-25 02:02 pm (UTC)
From: [identity profile] gerdlerin.livejournal.com
У меня немного иначе работает:

#!/usr/bin/perl

sub test1 () {
my $ret = 'level 11';
$$ret = 'level 21';
$$$ret = 'level 31';
return $ret;
}
sub test2 () {
my $ret = 'level 12';
$$ret = 'level 22';
$$$ret = 'level 32';
return $ret;
}
my $ref1 = test1();
my $ref2 = test2();
print $ref1,' ',$ref2, $/;
print $$ref1,' ',$$ref2, $/;
print $$$ref1,' ',$$$ref2, $/;


level 11 level 12
level 21 level 22
level 31 level 32
From: [identity profile] hobohabilis.livejournal.com
sub somesub {
	my $x     = 0;
	$x->{'key'} = "somesub: Hash key";
	$x->[0]   = "somesub: Array 0";
	$x
}

sub anothersub {
	# To stop dealing with garbage
	# simply assign $y to a value different from $x, e.g.: 0.1
	my $y 	  = 0.0;
	$y->{'key'} = "anothersub: Hash key";
	$y->[0]   = "anothersub: Array 0";
	$y
}

local $, = "\n";
print somesub(), somesub()->{'key'}, somesub()->[0],
	anothersub(), anothersub()->{'key'}, anothersub()->[0];


Ничего, прикольный такой фокус-покус. А как или где нарыли, если не секрет?
From: [identity profile] hobohabilis.livejournal.com
В принципе, если инициализировать лексические переменные каким-нибудь недорогим уникальным идентификатором типа (caller(0))[3] . '::varname_scopenumber', то использовать ваш трик во благо, наверное, можно и относительно безопасно в Perl 5. Некоторые разработчики иногда эксплуатируют ту же самую особенность подсистемы управления памятью Perl для имитации статических переменных:
sub SomeClass {
    my $instance = undef if undef;

    return $instance if defined $instance;

    require SomeClass;

    SomeClass->import();

    $instance = SomeClass->new();
}

From: [identity profile] hobohabilis.livejournal.com
Это у оптимистов она отпала, а пессимисты до сих пор не ответили на вопрос, насколько хорошо и слаженно их любимые CPAN модули могут работать с 5.10. Но state() - безусловно, очень ценное дополнение.
From: [identity profile] gerdlerin.livejournal.com
Большое спасибо за пояснение принципа работы, что-то самому сразу додуматься не удалось, т.к. символические ссылки в коде практически не использую!
Edited Date: 2009-06-26 08:19 am (UTC)
From: [identity profile] hobohabilis.livejournal.com
Не стоит благодарности. Тем более, что я и сам толком не знаю, что происходит в голове у Perl при выполнении предложенного кода. Но основные принципы шизофреничности таковы:

1). Для каждой лексической переменной память выделяется на этапе компиляции OP-кода, а не в процессе его выполнения.

2). К моменту возвращения из scope к которому относится лексическая переменная, выделенная ей память не высвобождается, если только не потребовать этого явным образом: undef($somevar)

3). Объем памяти, ассоциированный с лексической переменной, прямопропорционален самой объемной структуре данных, которая когда-либо этой переменной присваивалась.

4). Фактически, лексическая переменная - это указатель на внутренние структуры данных Perl, соотносящиеся с основными типами данных языка, и поэтому одновременно может одновременно "содержать" несколько значений, например: целое число, число с плавающей точкой, строка, массив, хэш и пр.

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

Profile

ocehb: (Default)
ocehb

January 2021

S M T W T F S
     12
345 6789
10111213141516
17181920212223
24252627282930
31      

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Feb. 6th, 2026 05:26 am
Powered by Dreamwidth Studios