For Programmers: Free Programming Magazines  


Home > Archive > PERL Beginners > October 2006 > Dynamical our/my/local









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Dynamical our/my/local
Oleg V. Volkov

2006-10-20, 3:58 am

Greetings.

Is there a way to do something to effect of:
our ${$varname};

I'm using a simple Getopt::* / Alias::attr like function to parse
named parameters from hash and assign them to localized variables
to save me some dereferencing inside heavy loops, but declaring
parameters two times - first as "our" variables and then once again
as a list for this function to check against, so it can catch
errors in list looks kinda ineffective to me.

--
Oleg "Rowaa[SR13]" V. Volkov
Jenda Krynicky

2006-10-20, 7:57 am

From: "Oleg V. Volkov" <rowaasr13@gmail.com>
> Greetings.
>
> Is there a way to do something to effect of:
> our ${$varname};
>
> I'm using a simple Getopt::* / Alias::attr like function to parse
> named parameters from hash and assign them to localized variables to
> save me some dereferencing inside heavy loops, but declaring
> parameters two times - first as "our" variables and then once again as
> a list for this function to check against, so it can catch errors in
> list looks kinda ineffective to me.


Have a look at

use vars qw($list @of %variables);

You should be able to do something like

our @allowed_list;
use vars map '$'.$_, (@allowed_list = qw(foo bar baz));

load_data( $source, \@allowed_list;

I don't think you can emulate 'local' or 'my'. You should also be aware of
the different scoping of the 'our' and 'use vars' declarations.

Jenda
===== Jenda@Krynicky.cz === http://Jenda.Krynicky.cz =====
When it comes to wine, women and song, wizards are allowed
to get drunk and croon as much as they like.
-- Terry Pratchett in Sourcery

Oleg V. Volkov

2006-10-20, 7:57 am

"Jenda Krynicky" <Jenda@krynicky.cz> wrote:
[skip][color=darkred]
> Have a look at
> use vars qw($list @of %variables);

[skip]
> I don't think you can emulate 'local' or 'my'. You should also be aware of
> the different scoping of the 'our' and 'use vars' declarations.


Yes, that's exactly why I don't want to "use vars". It takes away too
much benefits of "strict vars".

--
Oleg "Rowaa[SR13]" V. Volkov
Dr.Ruud

2006-10-20, 7:57 am

"Oleg V. Volkov" schreef:

> Is there a way to do something to effect of:
> our ${$varname};
>
> I'm using a simple Getopt::* / Alias::attr like function to parse
> named parameters from hash and assign them to localized variables
> to save me some dereferencing inside heavy loops, but declaring
> parameters two times - first as "our" variables and then once again
> as a list for this function to check against, so it can catch
> errors in list looks kinda ineffective to me.


Maybe use Data::Alias.

Or use an array with CONSTANTs for the indexes. Consider 'use enum'.

Provide code, so we can guess better.

--
Affijn, Ruud

"Gewoon is een tijger."
Randal L. Schwartz

2006-10-20, 7:57 am

>>>>> ""Oleg" == "Oleg V Volkov" <rowaasr13@gmail.com> writes:

"Oleg> I'm using a simple Getopt::* / Alias::attr like function to parse
"Oleg> named parameters from hash and assign them to localized variables
"Oleg> to save me some dereferencing inside heavy loops, but declaring
"Oleg> parameters two times - first as "our" variables and then once again
"Oleg> as a list for this function to check against, so it can catch
"Oleg> errors in list looks kinda ineffective to me.

I simply declare the variable and its default value directly
in GetOptions:

GetOptions(
"lhost=s" => \ (my $LOCALHOST = "localhost:0"),
"rhost=s" => \ (my $REMOTEHOST = "localhost:smtp"),
"connect=s" => \ (my $CONNECT),
"timeout=i" => \ (my $TIMEOUT = 30),
"quiet+" => \ (my $QUIET = 0),
"verbose+" => \ (my $VERBOSE = 0),
"<>" => sub { $Getopt::Long::error++; warn "Unknown arg: $_[0]\n" },
) or die "see code for usage\n";

print "Just another Perl hacker,"; # the original

--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<merlyn@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!
Oleg V. Volkov

2006-10-23, 7:57 am

"Dr.Ruud" <rvtol+news@isolution.nl> wrote:
> Provide code, so we can guess better.


Here's example how I use it in functions:

sub add_service{
our($login, $type_id, $account_id, $ap_id, $rule);
# Here we do some universal sanity checks for all add_* functions
attr({ croak_wrong_args(@_) });
print "Adding service type $type_id...\n";
# Here we do actual work
# ...
}

In this function I also would like to add croaking on passing
hash with keys that do not used in this function, but in this
solution this would require manually adding list of used/allowed
keys to call to sanitizing function, copying "our" declaration.

That's why I need to either find some way to stack "our" and
"croak_wrong_args" together, way to give "our" variable names
from list, so I can pass same list to "our" and to sanitizer
or to declare our variables one stack frame higher (which I
think is even less possible than first two).

--
Oleg "Rowaa[SR13]" V. Volkov
Jenda Krynicky

2006-10-23, 9:57 pm

From: "Oleg V. Volkov" <rowaasr13@gmail.com>
> "Dr.Ruud" <rvtol+news@isolution.nl> wrote:
>
> Here's example how I use it in functions:
>
> sub add_service{
> our($login, $type_id, $account_id, $ap_id, $rule);


Please DON'T!

You DO want to use

my ($login, $type_id, $account_id, $ap_id, $rule);

here, not our()! You do not want to access the GLOBAL variables
$main::login, $main::type_id, ..., you want to create your own
variables that belong just to this subroutine and nothing else. It
doesn't matter that you might have to specify something twice, but
using our() this way is simple dangerous. Don't.

Please read: http://perl.plover.com/FAQs/Namespaces.html

> # Here we do some universal sanity checks for all add_* functions
> attr({ croak_wrong_args(@_) }); print "Adding service type
> $type_id...\n"; # Here we do actual work # ...
> }
>
> In this function I also would like to add croaking on passing
> hash with keys that do not used in this function, but in this
> solution this would require manually adding list of used/allowed
> keys to call to sanitizing function, copying "our" declaration.
>
> That's why I need to either find some way to stack "our" and
> "croak_wrong_args" together, way to give "our" variable names
> from list, so I can pass same list to "our" and to sanitizer
> or to declare our variables one stack frame higher (which I
> think is even less possible than first two).


Maybe there are already modules that will do what you want and more.
And safer. Have a look at

Go to http://search.cpan.org/ and see
Params::Named, Sub::Parameters, Sub::Signatures, Params::Smart,
Perl6::Parameters, Sub::Parameters, ...

Maybe one of those will help you get where you are trying to go.

Jenda
===== Jenda@Krynicky.cz === http://Jenda.Krynicky.cz =====
When it comes to wine, women and song, wizards are allowed
to get drunk and croon as much as they like.
-- Terry Pratchett in Sourcery

Oleg V. Volkov

2006-10-24, 3:56 am

"Jenda Krynicky" <Jenda@krynicky.cz> wrote:
> Please DON'T!
> You DO want to use
> my ($login, $type_id, $account_id, $ap_id, $rule);


No. While I do want to use my, I, unfortunately, have to use globals,
because Alias::attr (and, as far as I understand all other
modules that perform namespace/glob tricks) operate exclusively
on globals.

> Maybe there are already modules that will do what you want and more.
> And safer. Have a look at
> Go to http://search.cpan.org/ and see
> Params::Named, Sub::Parameters, Sub::Signatures, Params::Smart,
> Perl6::Parameters, Sub::Parameters, ...


Though I didn't check entire list yet, I've seen some of them before
and they're either source filters or just expand arguments in some
kind of hash, which doesn't give me benefit of one-time dereference
that I get with aliasing arguments to variables either manually
or with Alias::attr, and this speed gain is the thing that I need
in functions with long loops.

--
Oleg "Rowaa[SR13]" V. Volkov
Dr.Ruud

2006-10-24, 7:57 am

"Oleg V. Volkov" schreef:

> Alias::attr (and, as far as I understand all other
> modules that perform namespace/glob tricks) operate
> exclusively on globals.


Did you check Data::Alias too?

From the examples:

alias my $fi = $self->{FrobnitzIndex};

This works a bit like

for my $fi ($self->{FrobnitzIndex}) { ... }

--
Affijn, Ruud

"Gewoon is een tijger."
Oleg V. Volkov

2006-10-24, 7:57 am

"Dr.Ruud" <rvtol+news@isolution.nl> wrote:
> Did you check Data::Alias too?


Really nice, but, alas, no Win32 and that's where I run most
of my stuff. It also wouldn be slower for functions that
are called often, because there's no functionality similar
to Alias' attr, which is XS.

Speaking of globals, AFAIK, I have virtually no drawbacks
against "my", as long as I use "our" variables inside
the scope. So what's bad there in using "our"?

--
Oleg "Rowaa[SR13]" V. Volkov
Oleg V. Volkov

2006-10-31, 7:56 am

"Oleg V. Volkov" <rowaasr13@gmail.com> wrote:
[skip]
> but declaring
> parameters two times - first as "our" variables and then once again
> as a list for this function to check against, so it can catch
> errors in list looks kinda ineffective to me.


Seems like I've found something that will help me. I still can't
do our/my with constructed names, but module PadWalker provides
a way to p into caller/arbitrary sub name space and this will
allow me to do checks based on declared variables.

--
Oleg "Rowaa[SR13]" V. Volkov
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2009 codecomments.com