oyse has asked for the wisdom of the Perl Monks concerning the following question:

Hi

Is it possible in anyway to add a Perl attribute to a value instead of to a variable?

If I understand the docs correctly the following code associates an attribute with a variable given that the attribute MyAttr is available.

my $var :MyAttr;
However I want to associate an attribute with a value and not with a variable. Something like this. Is this allowed in anyway?
my_func( 1, 'Hi there', { key => 'value } :MyAttr );

The above example could be solved by writing

my $var :MyAttr = { key => 'value' }; my_func( 1, 'Hi there', $var );

but that is not a satisfactory solutions in my case.

Also if an attribute cannot be associated with a value could anyone explain the reason behind this? I am wondering out of curiousity, it is not meant as a critisism to the attribute implementation in Perl.

Update: I no longer have use of actually doing this (see discussion below). I am however still curious if it is possible and if it is not, a possible explanation to why?

Replies are listed 'Best First'.
Re: Adding attributes to values?
by GrandFather (Saint) on Oct 21, 2007 at 09:26 UTC

    What is the problem you are trying to solve this way? Very likely there is a better solution to the bigger problem already available to you.


    Perl is environmentally friendly - it saves trees

      Well I am looking at making (yet another) module for adding signatures to Perl subroutines.

      I know that there are a lot of solutions to this problem already, but of course none of them works exactly like I want them to. The problem with them is generaly that you have to choose if you want positional argument passing or named argument passing, but a single subroutine cannot have both. I want it to be possible to pass the arguments either as positional arguments or as named arguments. The caller should decide what they want to use.

      To make that possible I need some way to distinguish a hash reference that contains named arguments and one that is just a normal argument. By associating an attribute with a hash refernence that might be possible.

      And yes I know I will probably not be able to make a module that is better than what already exists on CPAN, but you can't blame a guy for trying :) And I am learning a lot of Perl along the way.

        Hi,

        you might achieve concurrent use of named and positional args by doing the following:
        If a single hash_ref is passed, then treat it as single hash_ref containing named arguments. Otherwise consider them to be positional.

        For Example:
        sub get_args { if ((scalar(@_) == 1) && ref($_[0]) eq 'HASH') { print "got named args!\n"; } else { print "got positional args\n"; } } sub named_or_positional { get_args(@_); } named_or_positional({foo => 'avalue' , bar => ['a', 'b']}); named_or_positional('whatever' , 'we', 'are', 'passing');

        Only Limitation: you won't be able to use a single hash_ref as a positional argument (as it would be treated like an named arg). The Passing of named arguments as a hash ref is also recommended in "Perl Best Practices" by Damian Conway as it catches named arguments where the number of args is odd and not even(usually caused by some typo). This bears the advantage that you catch those typos at compile time and not at runtime.

        Personally I'd much rather well documented named parameters with sensible defaults and parameter checking by the called code. Positional parameter passing is simply not attractive unless there is only one (or no) parameter.


        Perl is environmentally friendly - it saves trees