Я сказал бы: дайте ребенку реальный C64, потому что это - то, как я начал. Но, сегодня... Я сказал бы Ruby, но Ruby немного слишком хаотичен. ОСНОВНОЙ было бы лучше в конечном счете. Обработку легко изучить, и это - в основном Java.
причина я рекомендую, чтобы C64 был то, потому что это является ОСНОВНЫМ, но все еще необходимо изучить определенные связанные с компьютером вещи, как модель памяти, пиксели, символы, карты символов, новые строки, и т.д. и т.д., если Вы хотите сделать более усовершенствованный материал. Кроме того, если Ваш ребенок находит его скучным, Вы знаете, что его основа действительно не в кодирование.
Мне пришлось пойти и посмотреть, как действительно неизменяемые языки делают что-то вроде это, и я думаю, что следующая попытка, вероятно, является разумной.
use 5.10.0;
{
package Node;
use Moose;
has [qw(parent child)] => ( isa => 'Node', is => 'ro' );
sub BUILD {
my ( $self, $p ) = @_;
return unless exists $p->{_child};
my $child = Node->new( parent => $self, %{ delete $p->{_child} }, );
$self->meta->get_attribute('child')->set_value( $self, $child );
}
}
say Node->new( _child => {} )->dump
По сути, вместо того, чтобы пытаться построить объекты по отдельности, у вас есть родитель автоматически оживляет ребенка, передавая ему аргументы. В вывод для этого - это, я полагаю, структура, которую вы хотели.
$VAR1 = bless( {
'child' => bless( {
'parent' => $VAR1
}, 'Node' )
}, 'Node' );
Вы можете играть в игры с отложенной инициализацией:
package Node;
use Moose;
has parent => (
is => 'ro',
isa => 'Node',
lazy => 1,
init_arg => undef,
builder => '_build_parent',
);
has _parent => (
is => 'ro',
init_arg => 'parent',
);
has child => (
is => 'ro',
isa => 'Node',
lazy => 1,
init_arg => undef,
builder => '_build_child',
);
has _child => (
is => 'ro',
init_arg => 'child',
predicate => undef,
);
has name => is => 'ro', isa => 'Str';
Генерация построителей и предикатов на лету:
BEGIN {
for (qw/ parent child /) {
no strict 'refs';
my $squirreled = "_" . $_;
*{"_build" . $squirreled} = sub {
my($self) = @_;
my $proto = $self->$squirreled;
ref $proto eq "REF" ? $$proto : $proto;
};
*{"has" . $squirreled} = sub {
my($self) = @_;
defined $self->$squirreled;
};
}
}
Это позволяет
my $a = Node->new(parent => \my $b, name => "A");
$b = Node->new(child => $a, name => "B");
for ($a, $b) {
print $_->name, ":\n";
if ($_->has_parent) {
print " - parent: ", $_->parent->name, "\n";
}
elsif ($_->has_child) {
print " - child: ", $_->child->name, "\n";
}
}
Его вывод
A:
- parent: B
B:
- child: A
Код мог бы быть более элегантным с η-преобразованием , но Moose не будет передавать параметры в методы построения.
Я все еще очень новичок в Moose, но хотел бы срабатывает триггер?
use Modern::Perl;
package Node;
use Moose;
has 'parent' => (
is => 'ro',
isa => 'Node',
trigger => sub{
my ($self, $parent) = @_;
$parent->{child} = $self unless defined $parent->child;
}
);
has 'child' => (
is => 'ro',
isa => 'Node',
trigger => sub{
my ($self, $child) = @_;
$child->{parent} = $self unless defined $child->parent;
}
);
package main;
my $p = Node->new;
my $c = Node->new(parent => $p);
say $p, ' == ', $c->parent;
say $c, ' == ', $p->child;