Should I choose a hash, object or array to represent a data instance in Perl?

I was always curious about this, but I never looked at it completely.

The situation is this: I have a relatively large set of data instances. Each instance has the same set or properties, for example:

# a child instance
name
age
height
weight
hair_color
favorite_color
list_of_hobbies

Normally, I would represent the child as a hash and contain all the children in the hash hash (or an array of hashes).

What has always bothered me with this approach is that I really do not use the fact that all children (internal hashes) have the same structure. It seems like it could be wasteful in memory if the data is really big, so if every internal hash is stored from scratch, it seems that the key name names can have a lot more meaning than the data itself ... Also note that when I I build such data structures, I often put nstorethem on disk.

I wonder if creating a child object makes sense in this perspective, although I don't need OO. Will it be more compact? Will the request be faster?

Or maybe representing each child as an array makes sense? eg:.

my ($name, $age, $height, $weight, $hair_color, $favorite_color, $list_of_hobbies) = 0..7; 
my $children_h = {
  James => ["James", 12, 1.62, 73, "dark brown", "blue", ["playing football", "eating ice-cream"]], 
  Norah => [...], 
  Billy => [...]
};
print "James height is $children_h->{James}[$height]\n";

, - (RAM ), (.. , x y) ... ( ..),.

!

+3
6
  • Perl , . 100 000 , perl . .

  • , , .

  • , Moose ( , , Moose , , - - .)

+11

, ( , , ) , , moose , . (, , , , )

, - . perl, moose

Gr, LDX

+2

, , Moose. .

, , . , . - , . , , . - :

my @all_hobbies = uniq map $_->all_hobbies, 
                       map $_->all_students, $school->all_classrooms;

. . , , . .

Moose . hobbies , .

package Child;

use Moose;

has [ 'name', 'hair_color', 'fav_color' ] => (
    is => 'ro',
    isa => 'Str',
    required => 1,
);

has [ 'age', 'height', 'weight' ] => (
    is => 'ro',
    isa => 'Num',
    required => 1,
);

has hobbies => (
    is      => 'ro',
    isa     => 'Int',
    default => sub {[]},
    traits  => ['Array'],
    handles   => {
        has_no_hobbies => 'is_empty',
        num_hobbies    => 'count',
        has_hobbies    => 'count',
        add_hobby      => 'push',
        clear_hobbies  => 'clear',
        all_hobbies    => 'elements',
    },
);

# Good to do these, see moose best practices manual.
__PACKAGE__->meta->make_immutable;
no Moose;

, Child:

use List::MoreUtils qw( zip );

# Bit of messing about to make array based child data into objects;

@attributes = qw( name age height weight hair_color fav_color hobbies );

my @children = map Child->new( %$_ ),
               map { zip @attributes, @$_ }, 
    ["James", 12, 1.62, 73, "dark brown", "blue",  ["playing football", "eating ice-cream"]], 
    ["Norah", 13, 1.75, 81, "black",      "red",   ["computer programming"]],
    ["Billy", 11, 1.31, 63, "red",        "green", ["reading", "drawing"]], 
;


# Now index by name:

my %children_by_name = map { $_->name, $_ } @children;

# Here we get kids with hobbies and print them.

for my $c ( grep $_->has_hobbies, @children ) {
    my $n = $c->name;
    my $h = join ", ", $c->all_hobbies;
    print "$n likes $h\n";
}
+2

, , , , . / .

, .

, . , , , , , .

+1

, , . Perl $something . , , , glob . , , .

, - :

use strict;
use warnings;
use constant {
  NAME            => 0,
  AGE             => 1,
  HEIGHT          => 2,
  WEIGHT          => 3,
  HAIR_COLOR      => 4,
  FAVORITE_COLOR  => 5,
  LIST_OF_HOBBIES => 6,
};

my $struct = ["James", 12, 1.62, 73, "dark brown", "blue", ["playing football", "eating ice-cream"]];

# And then access it with the constants as index:
print $struct->[NAME], "\n";
$struct->[AGE]++; # happy birthday!

, () :

package MyStruct;
use strict;
use warnings;
use Class::XSAccessor::Array
  accessors => {
    name => 0,
    age => 1,
    height => 2,
    weight => 3,
    hair_color => 4,
    favorite_color => 5,
    list_of_hobbies => 6,
  };

sub new {
  my $class = shift;
  return bless([@_] => $class);
}

package main;
my $s = MyStruct->new;
$s->name("James");
$s->age(12);
$s->height(1.62);
$s->weight(73);
# ... you get the drill, but take care: The following is fine:
$s->list_of_hobbies(["foo", "bar"]);
# This can produce action-at-a-distance:
my $hobbies = ["foo", "bar"];
$s->list_of_hobbies($hobbies);
$hobbies->[1] = "baz"; # $s changed, too (due to reference)

: , .

+1

, , , . . , refs vs - .

-, refs. , , - , , , . , (, ), , ( ) , - , (, , ..).

, - ref, . , - Perl, , , , . /, , , $my_obj->fix();, fix($my_obj);). , , .

/ . , , , , , , . , , , !

-1

Source: https://habr.com/ru/post/1767314/


All Articles