-1

Is it possible to return an alias from a subroutine in Perl?

I have a simple example:

#!/usr/bin/perl
use warnings;
use strict;
use feature qw{ say };

{
    package Test;
    my $value = 'old';

    sub get_value {
        return \$value;
    }

    sub set_value {
        my ($x) = @_;
        $value = $x;
    }
}

my $test = Test::get_value();
say $$test;

Test::set_value('new');
say $$test;

This is essentially the functionality I want, however I would like to find a way to make $test and alias to $value so I can access the data without dereferencing it. Is this possible?


Here is an example of the syntax I want:

ex (pseudo code):

#!/usr/bin/perl
use warnings;
use strict;
use feature qw{ say };

{
    package Test;
    my $value = 'old';

    sub get_value {
        # return alias to $value
    }

    sub set_value {
        my ($x) = @_;
        $value = $x;
    }
}

# Gets an alias, NOT a reference
my $test = Test::get_value();

# Print old
say $test;

Test::set_value('new');

# Print new
say $test;

I've been reading about aliases and everything keeps pointing to "typeglobs"... but it looks like using typeglobs requires the use of global variables and I would really like to avoid that.


Also I would like a solution that doesn't require installing any additional modules from CPAN since I need to get them approved by security and have them install it ... and so would anyone else here who wants to use my script.

tjwrona1992
  • 8,614
  • 8
  • 35
  • 98
  • 3
    You need to get code from CPAN reviewed but not code from SO? What if the code I post here is also found on CPAN? – ikegami Aug 06 '15 at 17:51
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/85337/discussion-between-tjwrona1992-and-ikegami). – tjwrona1992 Aug 06 '15 at 19:27

1 Answers1

2

First a word of warning. You are requesting information on performing an extremely poor practice. Actions at a distance should be eliminated, not sought.


You can bind two names to the same SV. A name bound as such is called an alias. You can't return a bound name, so you can't return an alias.

How about returning an object that overloads stringification?

$ perl -E'
   use String::Defer qw( );

   {
      my $value = "old";
      sub set_value { $value = $_[0] }
      sub get_value { String::Defer->new(\$value) }
   }

   {
      my $value = get_value();
      say $value;
      set_value('new');
      say $value;
   }
'
old
new

What you should do instead is return a reference.

$ perl -E'
   {
      my $value = "old";
      sub set_value { $value = $_[0] }
      sub get_ref { \$value }
   }

   {
      my $value_ref = get_ref();
      say $$value_ref;
      set_value('new');
      say $$value_ref;
   }
'
old
new
ikegami
  • 367,544
  • 15
  • 269
  • 518
  • I know this seems like very bad practice (and it probably is) but in the situation I'm using it in I want the value to be synchronized with an external data source. If the value in that data source is changed, I want the new value to be used. The user doesn't need to know that the value has changed, since the new value will always be valid. In fact, once the data changes, the old value would become invalid and could cause issues. I want to make it so the user doesn't have to manually retrieve the new value every time before they use the variable. – tjwrona1992 Aug 06 '15 at 18:13
  • At this point this has become more of an educational question, I would really just like to know if it is possible :) – tjwrona1992 Aug 06 '15 at 18:14
  • 1
    It doesn't seem to be a bad practice; it is. So much can go wrong. – ikegami Aug 06 '15 at 18:14