Delete array element from inside function

J

JS Bangs

Hey, all:

I've got a function that would like to be able to delete an array element
from an array in the caller's scope, given only the array element (not the
array itself, or a reference to it). The idea is to have something that
duplicates the functionality of delete(), but which tacks a bit of
other processing onto it. The existing code is quite simple, and looks
like this:

##########

sub delete_seg {
return undef unless is_segment($_[0]);
$_[0]->clear;
delete($_[0]);
}

#########

In the calling script (which has imported the function delete_seg()):

#########

delete_seg($word[3]);

#########

Unfortunately, this does not work. $word[3] remains firmly in place with a
defined value. What can I do to make this work?


Jesse S. Bangs (e-mail address removed)
http://students.washington.edu/jaspax/
http://students.washington.edu/jaspax/blog
 
A

Andrew Perrin

JS Bangs said:
Hey, all:

I've got a function that would like to be able to delete an array element
from an array in the caller's scope, given only the array element (not the
array itself, or a reference to it).

I don't think this is possible, since $word[3] is a scalar and
contains no reference to @word as a whole. If you don't need it to be
a general solution, and for some reason you're opposed to passing an
array ref, I suppose you could do something like:

$word[3] = {val => $word[3],
parent => \@word};
delete_seg($word[3]);

and then:

sub delete_seg {
my @parent = @{$_[0]->{parent}};
...
}

but I don't see why that would be useful.

Again, I don't think there's a general solution (but would be happy to
be proved wrong). You could also probably use tie() for a specific
solution, but again I think it's unlikely to be a better solution than
just passing the array ref.

ap
 
B

Brian McCauley

JS Bangs said:
I've got a function that would like to be able to delete an array element
from an array in the caller's scope, given only the array element (not the
array itself, or a reference to it). The idea is to have something that
duplicates the functionality of delete(), but which tacks a bit of
other processing onto it.

Short answer is you can't.

Slightly longer answer is defined(prototype("CORE::delete")) is false
meaning that the inbuilt delete() cannot be simulated by a subroutine.

Slightly longer answer still is that the scalars that are elements of
an array have an existance independant of the array. When I delete()
the second element of an array it has no actual effect on the the
scalar that holds the second element, instead if just disconnects if
from the array.

my @array = (1,2,3);
my $r = \$array[1];
delete $array[2];
print $$r;

Similarly if I use the for() or subroutine call mechansims to make $_
or and element of @_ into an alias for an array element it becomes an
alias to the scalar that contains the value of the array element - the
alias is in no way associated with the array.
The existing code is quite simple, and looks
like this:

##########

sub delete_seg {
return undef unless is_segment($_[0]);
$_[0]->clear;
delete($_[0]);
}

#########

In the calling script (which has imported the function delete_seg()):

#########

delete_seg($word[3]);

#########

Unfortunately, this does not work. $word[3] remains firmly in place with a
defined value. What can I do to make this work?

You cannot, you need to avoid wanting to do it.

Without more background I can't be sure, but at a guess I'd say you
appear to be trying to work arround the misconception that Perl
doesn't have destructors.

If this is the case forget about delete_seg() function totally and
rename the 'clear' method to 'DESTROY'.

--
\\ ( )
. _\\__[oo
.__/ \\ /\@
. l___\\
# ll l\\
###LL LL\\
 
J

John W. Krahn

JS said:
I've got a function that would like to be able to delete an array element
from an array in the caller's scope, given only the array element (not the
array itself, or a reference to it). The idea is to have something that
duplicates the functionality of delete(), but which tacks a bit of
other processing onto it. The existing code is quite simple, and looks
like this:

##########

sub delete_seg {
return undef unless is_segment($_[0]);
$_[0]->clear;
delete($_[0]);
}

#########

In the calling script (which has imported the function delete_seg()):

#########

delete_seg($word[3]);

#########

Unfortunately, this does not work. $word[3] remains firmly in place with a
defined value. What can I do to make this work?

It looks like you need to use splice:

splice @word, 3, 1;



John
 
J

JS Bangs

Brian McCauley sikyal:
Short answer is you can't.

Slightly longer answer is defined(prototype("CORE::delete")) is false
meaning that the inbuilt delete() cannot be simulated by a subroutine.

Which also means that delete() is not goto-able, as a simple test
revealed. Well, drat. That was my last hope.
Unfortunately, this does not work. $word[3] remains firmly in place with a
defined value. What can I do to make this work?

You cannot, you need to avoid wanting to do it.

It sure looks like I do.
Without more background I can't be sure, but at a guess I'd say you
appear to be trying to work arround the misconception that Perl
doesn't have destructors.

Nah, I'm not worried about object destruction. The kink here is that I
often want to "delete" a segment object, but "deletion" can take the form
of actually delete()-ing it, or in clearing all of its values, depending
on context. I was hoping to have a function that would do both and so
avoid me having to think about the difference.



Jesse S. Bangs (e-mail address removed)
http://students.washington.edu/jaspax/
http://students.washington.edu/jaspax/blog

Jesus asked them, "Who do you say that I am?"

And they answered, "You are the eschatological manifestation of the ground
of our being, the kerygma in which we find the ultimate meaning of our
interpersonal relationship."

And Jesus said, "What?"
 
I

Islaw

Andrew said:
JS Bangs said:
Hey, all:

I've got a function that would like to be able to delete an array
element from an array in the caller's scope, given only the array
element (not the array itself, or a reference to it).

I don't think this is possible, since $word[3] is a scalar and
contains no reference to @word as a whole. If you don't need it to be
a general solution, and for some reason you're opposed to passing an
array ref, I suppose you could do something like:

$word[3] = {val => $word[3],
parent => \@word};
delete_seg($word[3]);

and then:

sub delete_seg {
my @parent = @{$_[0]->{parent}};
...
}

but I don't see why that would be useful.

Again, I don't think there's a general solution (but would be happy to
be proved wrong). You could also probably use tie() for a specific
solution, but again I think it's unlikely to be a better solution than
just passing the array ref.

Very creative though! (If a tad overkill for the task at hand.) As you
mentioned, a array ref would be a bit cleaner (and more general.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top