Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Implicit iterator variable $_ changing to ### upon variable assignment?

Reply
Thread Tools

Implicit iterator variable $_ changing to ### upon variable assignment?

 
 
Derek Basch
Guest
Posts: n/a
 
      08-11-2006
Hello all,

I have ran into a very confusing problem and I hoped someone could help
me. This function is supposed to return a hash of the accessors and
their associated values for a given class.


------------------------------------------
package Test;

sub accessors_values {
my $self = shift;
my %accessors_values;

foreach $_ ($self->accessors()) {
print "$_\n";
my $value = $self->_accessor_class($_)->get($_);
print "$_ : $value\n";
}
return %accessors_values;
}

.........

------------------------------------------

Gives this output:
------------------------------------------
password
### : carefree
user_id
### : 323227
first_login
### : 2006.08.08.12.47.13
last_login
### : 2006.08.08.12.47.13
------------------------------------------

Where the heck is the '###' coming from? How is assigning a value to
the $value variable causing the implicit iterator variable $_ to become
'###' ?

The functions that the code calls are large so I will give a synopsis
of what they return:

$self->accessors returns an array of accessor names
$self->_accessor_class returns a hash ref to a class
$self->get returns a scalar value

Any help is greatly appreciated.

Thanks,
Derek Basch

 
Reply With Quote
 
 
 
 
Derek Basch
Guest
Posts: n/a
 
      08-11-2006

Derek Basch wrote:
> Hello all,
>
> I have ran into a very confusing problem and I hoped someone could help
> me. This function is supposed to return a hash of the accessors and
> their associated values for a given class.
>
>
> ------------------------------------------
> package Test;
>
> sub accessors_values {
> my $self = shift;
> my %accessors_values;
>
> foreach $_ ($self->accessors()) {
> print "$_\n";
> my $value = $self->_accessor_class($_)->get($_);
> print "$_ : $value\n";
> }
> return %accessors_values;
> }
>
> ........
>
> ------------------------------------------
>
> Gives this output:
> ------------------------------------------
> password
> ### : carefree
> user_id
> ### : 323227
> first_login
> ### : 2006.08.08.12.47.13
> last_login
> ### : 2006.08.08.12.47.13
> ------------------------------------------
>
> Where the heck is the '###' coming from? How is assigning a value to
> the $value variable causing the implicit iterator variable $_ to become
> '###' ?
>
> The functions that the code calls are large so I will give a synopsis
> of what they return:
>
> $self->accessors returns an array of accessor names
> $self->_accessor_class returns a hash ref to a class
> $self->get returns a scalar value
>
> Any help is greatly appreciated.
>
> Thanks,
> Derek Basch


I answered my own question. The implicit iterator was apparently being
set to "##" by one of the functions that I called from within the sub.
I didn't realize that it could be affected in such a way. Live and
learn I guess.

Thanks Anyways,
Derek Basch

 
Reply With Quote
 
 
 
 
Derek Basch
Guest
Posts: n/a
 
      08-11-2006

Derek Basch wrote:
> Derek Basch wrote:
> > Hello all,
> >
> > I have ran into a very confusing problem and I hoped someone could help
> > me. This function is supposed to return a hash of the accessors and
> > their associated values for a given class.
> >
> >
> > ------------------------------------------
> > package Test;
> >
> > sub accessors_values {
> > my $self = shift;
> > my %accessors_values;
> >
> > foreach $_ ($self->accessors()) {
> > print "$_\n";
> > my $value = $self->_accessor_class($_)->get($_);
> > print "$_ : $value\n";
> > }
> > return %accessors_values;
> > }
> >
> > ........
> >
> > ------------------------------------------
> >
> > Gives this output:
> > ------------------------------------------
> > password
> > ### : carefree
> > user_id
> > ### : 323227
> > first_login
> > ### : 2006.08.08.12.47.13
> > last_login
> > ### : 2006.08.08.12.47.13
> > ------------------------------------------
> >
> > Where the heck is the '###' coming from? How is assigning a value to
> > the $value variable causing the implicit iterator variable $_ to become
> > '###' ?
> >
> > The functions that the code calls are large so I will give a synopsis
> > of what they return:
> >
> > $self->accessors returns an array of accessor names
> > $self->_accessor_class returns a hash ref to a class
> > $self->get returns a scalar value
> >
> > Any help is greatly appreciated.
> >
> > Thanks,
> > Derek Basch

>
> I answered my own question. The implicit iterator was apparently being
> set to "##" by one of the functions that I called from within the sub.
> I didn't realize that it could be affected in such a way. Live and
> learn I guess.
>
> Thanks Anyways,
> Derek Basch


Note that the way I found this error was by trying to do this:

%accessors_values = map { $iter =>
$self->_accessor_class($iter)->get($iter) } $self->accessors();

The foreach above was my attempt to break the problem into smaller
units for testing.
So, you can solve this problem by not using the implicit iterator with
a foreach loop.

What I didn't mention was that the get function above uses a "while
<FILEHANDLE>"
loop. The "while <FILEHANDLE>" loop uses an implicit iterator and the
map function also uses an implicit iterator.

So, if you use map with an EXPR that uses the "while <FILEHANDLE>"
idiom the map implicit iterator value will be replaced with the "while
<FILEHANDLE>" implicit iterator value. You must use foreach instead of
map.

I hope that helps someone in the future

Derek Basch

 
Reply With Quote
 
Derek Basch
Guest
Posts: n/a
 
      08-11-2006

Michele Dondi wrote:
> On 11 Aug 2006 13:34:56 -0700, "Derek Basch" <(E-Mail Removed)> wrote:
>
> > foreach $_ ($self->accessors()) {
> > print "$_\n";
> > my $value = $self->_accessor_class($_)->get($_);

> ^^ ^^
> ^^ ^^
>
> [snip]
>
> >$self->accessors returns an array of accessor names

>
> So far so fine.
>
> >$self->_accessor_class returns a hash ref to a class

>
> Which happens to be... what?!?


A subclass of Class::Accessor.

> And what does it expect as an argument?


An accessor name.

>
> >$self->get returns a scalar value

>
> And what does it expect as an argument?


An accessor name.

> But most importantly in the code above get() is not a method of $self,
> but of the object _accessor_class($_).


Yes, $self is an aggregated class and the get methods are different for
each aggregated class.

Class_B <---has a---$self----has a---> Class_A
| |
v v
sub get() sub get()

> All in all it seems *strange*, although not strictly impossible, that
> you want to pass $_ to both methods above.


$self uses the name of the accessor (_accessor_class) to determine
which aggregated class has the proper get function. get takes the
accessor name to know which value to get.

> Also the fact that
> accessors() returns an array of accessor names suggest that you are
> fiddling with symrefs. You may return proper $method refs, and call
> them like thus instead:
>
> my $value = $self->$method(...);


I suppose calling:

get('accessor_name')

is essentially like using a symref but I think this is what would be
what would be considered a true symref call:

foreach $_ ($self->accessors()) {
my $value = $self->_accessor_class($_)->$_;
}

The only other way I can think of to handle this would be to return a
hash of method references from the accessors() function:

foreach $_ ($self->accessors()) {
my $value = $self->_accessor_class($_)->{'$_'};
}

and isn't that exactly what a class hash reference is in Perl?

I apologize for not being verbose enough with my example but I didn't
want to put 300 lines of code in my message. 300 lines would have been
the concise version too.

Thanks for the help,
Derek Basch





OkbridgeDatabase::Gps->mk_accessors(OkbridgeDatabase::Gps->accessors());

sub accessors {
my @accessors = (
'password',
'user_id',
'first_login',
'last_login',




>
> To make a long story short: hard to say anything without looking at
> the rest of your code. So, as usual, may you prepare a suitable
> minimal but complete example exhibiting the problem? Also you'd better
> state more clearly what you're actually trying to do.
>
>
> Michele
> --
> {$_=pack'B8'x25,unpack'A8'x32,$a^=sub{pop^pop}->(map substr
> (($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^<R<Y]*YB='
> .'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,$_,
> 256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,


 
Reply With Quote
 
Mumia W.
Guest
Posts: n/a
 
      08-11-2006
On 08/11/2006 04:22 PM, Derek Basch wrote:
> Derek Basch wrote:
>> Derek Basch wrote:
>>> Hello all,
>>>
>>> I have ran into a very confusing problem and I hoped someone could help
>>> me. This function is supposed to return a hash of the accessors and
>>> their associated values for a given class.
>>>
>>>
>>> ------------------------------------------
>>> package Test;
>>>
>>> sub accessors_values {
>>> my $self = shift;
>>> my %accessors_values;
>>>
>>> foreach $_ ($self->accessors()) {
>>> print "$_\n";
>>> my $value = $self->_accessor_class($_)->get($_);
>>> print "$_ : $value\n";
>>> }
>>> return %accessors_values;
>>> }
>>>
>>> ........
>>>
>>> ------------------------------------------
>>>
>>> Gives this output:
>>> ------------------------------------------
>>> password
>>> ### : carefree
>>> user_id
>>> ### : 323227
>>> first_login
>>> ### : 2006.08.08.12.47.13
>>> last_login
>>> ### : 2006.08.08.12.47.13
>>> ------------------------------------------
>>>
>>> Where the heck is the '###' coming from? How is assigning a value to
>>> the $value variable causing the implicit iterator variable $_ to become
>>> '###' ?
>>>
>>> The functions that the code calls are large so I will give a synopsis
>>> of what they return:
>>>
>>> $self->accessors returns an array of accessor names
>>> $self->_accessor_class returns a hash ref to a class
>>> $self->get returns a scalar value
>>>
>>> Any help is greatly appreciated.
>>>
>>> Thanks,
>>> Derek Basch

>> I answered my own question. The implicit iterator was apparently being
>> set to "##" by one of the functions that I called from within the sub.
>> I didn't realize that it could be affected in such a way. Live and
>> learn I guess.
>>
>> Thanks Anyways,
>> Derek Basch

>
> Note that the way I found this error was by trying to do this:
>
> %accessors_values = map { $iter =>
> $self->_accessor_class($iter)->get($iter) } $self->accessors();
>
> The foreach above was my attempt to break the problem into smaller
> units for testing.
> So, you can solve this problem by not using the implicit iterator with
> a foreach loop.
>
> What I didn't mention was that the get function above uses a "while
> <FILEHANDLE>"
> loop. The "while <FILEHANDLE>" loop uses an implicit iterator and the
> map function also uses an implicit iterator.
>
> So, if you use map with an EXPR that uses the "while <FILEHANDLE>"
> idiom the map implicit iterator value will be replaced with the "while
> <FILEHANDLE>" implicit iterator value. You must use foreach instead of
> map.
>
> I hope that helps someone in the future
>
> Derek Basch
>


Indeed it probably will; it'll remind people to use local

#!/usr/bin/perl

package Tryit;
use strict;
use warnings;

my @fun = map { get(); $_ } (1..4);
print "@fun\n";

sub get {
# What happens when you comment out the "local"
# below?
local $_;
while (<DATA>) {
last if /###/;
}
}

__DATA__
nothing here
### more hash marks ###
 
Reply With Quote
 
Ben Morrow
Guest
Posts: n/a
 
      08-12-2006

Quoth Michele Dondi <(E-Mail Removed)>:
> On 11 Aug 2006 13:34:56 -0700, "Derek Basch" <(E-Mail Removed)> wrote:
>
> you want to pass $_ to both methods above. Also the fact that
> accessors() returns an array of accessor names suggest that you are
> fiddling with symrefs.


Methods are looked up by name at runtime, so they're effectively symrefs
anyway.

> You may return proper $method refs, and call
> them like thus instead:
>
> my $value = $self->$method(...);


....but whay would be the advantage in doing so, except in rather weird
circumstances?

Ben

--
Although few may originate a policy, we are all able to judge it.
Pericles of Athens, c.430 B.C.
http://www.velocityreviews.com/forums/(E-Mail Removed)
 
Reply With Quote
 
Uri Guttman
Guest
Posts: n/a
 
      08-12-2006
>>>>> "MW" == Mumia W <(E-Mail Removed)> writes:

MW> On 08/11/2006 04:22 PM, Derek Basch wrote:

>> Note that the way I found this error was by trying to do this:
>> %accessors_values = map { $iter =>
>> $self->_accessor_class($iter)->get($iter) } $self->accessors();
>> The foreach above was my attempt to break the problem into smaller
>> units for testing.
>> So, you can solve this problem by not using the implicit iterator with
>> a foreach loop.
>> What I didn't mention was that the get function above uses a "while
>> <FILEHANDLE>" loop. The "while <FILEHANDLE>" loop uses an implicit
>> iterator and the map function also uses an implicit iterator.
>> So, if you use map with an EXPR that uses the "while <FILEHANDLE>"
>> idiom the map implicit iterator value will be replaced with the
>> "while <FILEHANDLE>" implicit iterator value. You must use foreach
>> instead of map.
>> I hope that helps someone in the future
>> Derek Basch
>>


MW> Indeed it probably will; it'll remind people to use local

better if it reminds people to not use $_ all the time. with loops it is
much better to use a lexical var and then you never can have anything
like this happen. and your code becomes easier to read as you have a
named variable for each loop and it is lexical and never is seen by any
called subs or maps.

uri

--
Uri Guttman ------ (E-Mail Removed) -------- http://www.stemsystems.com
--Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
 
Reply With Quote
 
Derek Basch
Guest
Posts: n/a
 
      08-12-2006

> It seems that in the end you're more knowledgeable than I am, because
> as above I don't have the slightest idea of what a "class hash
> reference" could be. A class is a package. The only hash that comes to
> mind speaking of the latter, is its stash. Or else objects are often
> implemented by means of blessed hash references "containing" the data,
> but that's just one implementation choice. In any case I'm not really
> sure about what you're talking about and I must be missing something,
> sorry!



I guess I should read up more on the differences between a package
stash and blessed hash references as objects. I had been thinking they
were the same thing but apparently they are not.

Thanks for the help everyone,
Derek Basch

 
Reply With Quote
 
Ben Morrow
Guest
Posts: n/a
 
      08-12-2006

[please attribute quotes]

Quoth "Derek Basch" <(E-Mail Removed)>:
> Michele Dondi <(E-Mail Removed)> wrote:
> >
> > It seems that in the end you're more knowledgeable than I am, because
> > as above I don't have the slightest idea of what a "class hash
> > reference" could be. A class is a package. The only hash that comes to
> > mind speaking of the latter, is its stash. Or else objects are often
> > implemented by means of blessed hash references "containing" the data,
> > but that's just one implementation choice. In any case I'm not really
> > sure about what you're talking about and I must be missing something,
> > sorry!

>
> I guess I should read up more on the differences between a package
> stash and blessed hash references as objects. I had been thinking they
> were the same thing but apparently they are not.


Don't worry about package stashes: they are an advanced topic that
you'll likely never need to worry about. The source of Michele's
confusion is that you are mixing up the terms 'class' and 'object'. What
you meant to say instead of 'a class hash reference' was 'a reference to
an object' or 'a reference to a blessed hash'. The former is preferable
as the fact that the object is implemented as a blessed hash is not (or
should not be) important to users of that object.

A class is a type of object. It is represented in Perl by its name,
either as a string or as a bareword. So in

my $fb = Foo::Bar->new;

'Foo::Bar' is a class. The ->new method will be passed the string
'Foo::Bar' as its first argument.

An object is an instance of a class: that is, an object is to a class as
'1' is to 'the integers'. If ->new in the above is a normal constructor,
then $fb will hold a reference to an object. Objects in Perl can only be
accessed through references to them.

An object responds to certain methods: these are defined in the class in
class-based OO systems (which Perl's is, usually). However, it is
important to realize that calling a method on an object and calling it
on the class are quite different operations; most methods can only be
called on one or the other.

Ben

--
Musica Dei donum optimi, trahit homines, trahit deos. |
Musica truces mollit animos, tristesque mentes erigit.|(E-Mail Removed)
Musica vel ipsas arbores et horridas movet feras. |
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Changing the imageurl of an imagemap control upon postback BillGatesFan ASP .Net 1 02-15-2008 07:57 PM
Implicit conversion of iterator to reverse_iterator bb C++ 3 04-30-2007 06:33 PM
Difference between Java iterator and iterator in Gang of Four Hendrik Maryns Java 18 12-22-2005 05:14 AM
RAA-stream implicit iterator maybe offbyone ? Simon Strandgaard Ruby 2 09-17-2003 06:02 PM
Iterator doubts, Decision on Iterator usage greg C++ 6 07-17-2003 01:26 PM



Advertisments