Ovid <[EMAIL PROTECTED]> writes: > --- Barry Jones <[EMAIL PROTECTED]> wrote: >> If I have a hash full of values, and some of those values point to >> arrays of more values...in a loop, how could I distinguish which ones >> pointed to an array and which were just string values? > > Barry, > > Use the 'ref' function for this: > > perldoc -f ref > > One caveat, though: most uses of 'ref' seem wrong. Generally > speaking, whenever I am tempted to use ref on vanilla code, I > discover that I could simplify what I meant to do. In your case, > have you considered making every value an array reference? If you > only have a scalar, you have a one-element array ref. Generally, > when I rework the code to eliminate the need for 'ref', I discover > that my code is shorter and easier to maintain. > > I'm not saying that you've done anything wrong, of course. I'm just > suggesting that you might want to give the code a second look.
Depending on what the hash is being used for and whether the structure is arbitrary, this may be a good time pull out the old OO toolkit, specifically the 'Composite' and 'Visitor' patterns. The idea here is that you have a treelike data structure made up of containers and 'terminals'. You could then setup some classes like so: package Container; sub accept { my $self = shift; my($visitor) = @_; $visitor->visit_container($self); foreach my $element ($self->contents) { $element->accept($visitor); } $visitor->leave_container($self); } sub contents { my $self = shift; wantarray ? @{$self->{contents}} : $self->{contents}; } sub name { my $self = shift; $self->{name}; } package Terminal; sub accept { my $self = shift; my($visitor) = @_; $visitor->visit_terminal($self); } sub name { $self->{name}; } So, suppose we use this data structure to represent a filesystem and we want to list all the files in it, so, we write ourselves a visitor: package FileLister; sub visit_container { my $self = shift; my($directory) = @_; $self->push_path($directory->name); } sub visit_terminal { my $self = shift; my($file) = @_; print join '/', $self->path, $file->name; } sub leave_container { my $self = shift; my($directory) = @_; ($directory->name eq $self->pop_path) or die "Something very strange happened"; } NB: This is very skeletal there's no denyinig. Implementing constructors, other accessor methods and all the other paraphenalia of a fully functional class is left as an exercise for the interested reader. This is a very powerful approach; you'll come across it in all manner of places. There's all sorts of wrinkles you can add, for instance, you might extend the interface to allow the various vist_* methods to prune the tree walk by cunning use of return values or exceptions. There's no denying that it carries a bunch of overhead with it though, and it's not suited to everything; but it's a useful tool to know about. -- Piers "It is a truth universally acknowledged that a language in possession of a rich syntax must be in need of a rewrite." -- Jane Austen? -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]