Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer

Linked List Strangeness

by Mandor (Pilgrim)
on Jan 31, 2002 at 17:25 UTC ( #142460=perlquestion: print w/replies, xml ) Need Help??
Mandor has asked for the wisdom of the Perl Monks concerning the following question:

Since we've been doing linked lists in computer science
class recently but are unfortunately using the ol' Pascal
(which I've grown to dislike) I decided to code the same
simple program we finished in class - this time in Perl to see how it works.
After reading a little on that topic I made an implementation
like this :
use strict; my $list = undef; my $lastnode = \$list; while (1) { print '<i>nput, <o>utput : '; chomp (my $input = <STDIN>); if ($input eq 'i') { ($list, $lastnode) = add ($list, $lastnode); next; } if ($input eq 'o') { show ($list); next; } } sub add { my ($list, $lastnode) = @_; chomp (my $input = <STDIN>); my $newnode = [undef, $input]; $$lastnode = $newnode; $lastnode = \$newnode -> [0]; return ($list, $lastnode); } sub show { my $list = shift; for (my $node = $list; $node; $node = $node -> [0]) { print $node -> [1] . "\n"; } }
Interestingly I found out that this wasn't working.
Debugging it with Komodo 1.1 I found that after
$$lastnode = $newnode;
$list wasn't being set, which kinda defeated it's purpose.
Then I changed the implementation to this :
use strict; my $list = undef; my $lastnode = \$list; while (1) { print '<i>nput, <o>utput : '; chomp (my $input = <STDIN>); if ($input eq 'i') { &add; next; } if ($input eq 'o') { &show; next; } } sub add { chomp (my $input = <STDIN>); my $newnode = [undef, $input]; $$lastnode = $newnode; $lastnode = \$newnode -> [0]; } sub show { for (my $node = $list; $node; $node = $node -> [0]) { print $node -> [1] . "\n"; } }
I removed the variable passing and accessed $list and $lastnode directly.
And well, now it worked. But I don't get why passing the variable
makes example 1 don't work.

I am thankful for enlightenment.

Replies are listed 'Best First'.
(tye)Re: Linked List Strangeness
by tye (Sage) on Jan 31, 2002 at 17:55 UTC

    Let me make a tiny change so that I can talk about this more easily. The problem is that one $list is being changed while the other $list isn't. So lets rename one of them:

    use strict; my $list = { head=>undef, tail=>undef }; while (1) { print '<i>nput, <o>utput : '; chomp (my $input = <STDIN>); if ($input eq 'i') { add($list); next; } if ($input eq 'o') { show($list); next; } } sub add { my ($list) = @_; chomp (my $input = <STDIN>); my $newnode = [undef, $input]; $list{tail}[0]= $newnode; $list{tail}= $newnode; }
    The problem is that $list is updated when you modify $$lastnode, but my ($root, $lastnode) = @_; makes $root a copy of $list and so $root is not changed. Then add() returns $root and, in effect, you end up doing $list= $root, which restores $list to its previous value.

    You could change the last line of add() to be return ($_[0], $lastnode); since $_[0] is an alias to $list and not a copy of $list.

    But better would be to encapsulate the $list and $lastnode variables into a single item that is passed to add() and show().

            - tye (but my friends call me "Tye")

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://142460]
Approved by root
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others exploiting the Monastery: (10)
As of 2018-06-18 18:07 GMT
Find Nodes?
    Voting Booth?
    Should cpanminus be part of the standard Perl release?

    Results (110 votes). Check out past polls.