pointer to constructor to a class in perl6

拥有回忆 提交于 2019-12-04 03:19:11

问题


I am trying to write some classes with Perl 6 just for testing out Perl 6 classes and methods.

Here is the code:

class human1 {
    method fn1() {
        print "#from human1.fn1\n";
    }
}

class human2 {
    method fn1() {
          print "#from human2.fn1\n";
    }
}

my $a = human1.new();
my $b = human2.new();

$a.fn1();
$b.fn1();

print "now trying more complex stuff\n";

my $hum1_const = &human1.new;
my $hum2_const = &human2.new;

my $c = $hum2_const();
$c.fn1();

Essentially I want to be able to use either the human1 constructor or human2 constructor to be able to build $c object dynamically. But I'm getting the following error:

Error while compiling /usr/bhaskars/code/perl/./a.pl6
Illegally post-declared types:
    human1 used at line 23
    human2 used at line 24

How do I create $c using the function pointers to choose which constructor I use?


回答1:


I think this is a case of an LTA error. What I understand you want to achieve, is a lambda that will create a new human1 or human2 object for you. The way you do that is not correct, and the error it causes is confusing.

my $hum1_const = -> { human1.new };
my $hum2_const = -> { human2.new };

would be a correct way of doing this. Although, I would consider this a bit of an obfuscation. Since human1 and human2 are already constants, you can assign them to a variable, and then just call new on that:

my $the_human = $condition ?? human1 !! human2;
my $c = $the_human.new;
$c.fn1;

Does that make sense?




回答2:


To get a “reference” to .new you have to use the meta object protocol.
Either .^lookup, or .^find_method.

my $hum1-create = human1.^find_method('new');

That is still not quite what you are looking for, as methods require either a class object or an instance, as their first argument.

my $c = $hum1-create( human1 );

So you would probably want to curry the class as the first argument to the method.

my $hum1-create = human1.^find_method('new').assuming(human1);

my $c = $hum1-create();

Note that .assuming in this case basically does the same thing as

-> |capture { human1.^find_method('new').( human1, |capture ) }

So you could just write:

my $hum1-create = -> |capture { human1.new( |capture ) }

Or if you are never going to give it an argument

my $hum1-create = -> { human1.new }

Also you can store it in a & sigiled variable, so you can use it as if it were a normal subroutine.

my &hum1-create = human1.^find_method('new').assuming(human1);

my $c = hum1-create;


来源:https://stackoverflow.com/questions/47994213/pointer-to-constructor-to-a-class-in-perl6

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!