Я думаю, что суть утиной печати заключается в том, как она используется. Один использует метод обнаружения и самоанализа сущности для того, чтобы узнать, что с ним делать, вместо того, чтобы заранее объявлять, чем он будет * (где вы знаете, что с ним делать).
Вероятно, это более практично в ОО-языках, где примитивы не являются примитивами, а являются объектами.
Я думаю, что лучший способ подвести итог, в варианте типа, сущность есть / может быть чем угодно, и что это неопределенно, в отличие от сущности только выглядит как что-либо, но вы можно выяснить, что это, спросив об этом.
Вот кое-что, что я не верю, правдоподобно без утки.
sub dance {
my $creature = shift;
if( $creature->can("walk") ){
$creature->walk("left",1);
$creature->walk("right",1);
$creature->walk("forward",1);
$creature->walk("back",1);
}
if( $creature->can("fly") ){
$creature->fly("up");
$creature->fly("right",1);
$creature->fly("forward",1);
$creature->fly("left", 1 );
$creature->fly("back", 1 );
$creature->fly("down");
} else if ( $creature->can("walk") ) {
$creature->walk("left",1);
$creature->walk("right",1);
$creature->walk("forward",1);
$creature->walk("back",1);
} else if ( $creature->can("splash") ) {
$creature->splash( "up" ) for ( 0 .. 4 );
}
if( $creature->can("quack") ) {
$creature->quack();
}
}
my @x = ();
push @x, new Rhinoceros ;
push @x, new Flamingo;
push @x, new Hyena;
push @x, new Dolphin;
push @x, new Duck;
for my $creature (@x){
new Thread(sub{
dance( $creature );
});
}
Любой другой способ потребовал бы, чтобы вы накладывали ограничения на типы для функций, которые вырезали бы разные виды, требовали от вас создавать разные функции для разных видов, что делало код действительно адским для поддержки.
И это действительно отстой с точки зрения просто попытки выполнить хорошую хореографию.