How do I declare a class attribute as a union of class names?

前端 未结 3 1901
别那么骄傲
别那么骄傲 2021-01-12 08:41

I\'m reading a spreadsheet looking for different structures. When I tried the following using Moose it seems to do what I want. I could create different types of objects, as

3条回答
  •  清酒与你
    2021-01-12 09:06

    Here is a fully working implementation of the subset/where solution mentioned by Brad Gilbert in his answer. This includes one example for each of the classes in Common and also one example that shows what happens when type constraints aren't met:

    #!/bin/env perl6
    
    class  Sch-Symbol { has Str $.name }
    class Chip-Symbol { has Num $.num  }
    class         Net { has Int $.id   }
    
    subset Common of Any where Sch-Symbol|Chip-Symbol|Net;
    
    class Cell {
      has Str $.str_val  is required;
      has Str $.x_id     is required;
      has Str $.color;
      has Str $.border;
      has Common $.found is rw;
    }
    
    my $str_val = 'foo';
    my $x_id    = 'bar';
    
    my @founds = (
        Net.new(:42id),                 # will work
        Sch-Symbol.new(:name),     # will work
        Chip-Symbol.new(num => 1E101),  # will work
        42,                             # won't work
    );
    
    for @founds -> $found {
       my $cell =  Cell.new(:$str_val, :$x_id, :$found);
       dd $cell;
    }
    

    Assuming this is in the file test.p6, when we run perl6 test.p6 we get:

    Cell $cell = Cell.new(str_val => "foo", x_id => "bar", color => Str, border => Str, found => Net.new(id => 42))
    Cell $cell = Cell.new(str_val => "foo", x_id => "bar", color => Str, border => Str, found => Sch-Symbol.new(name => "baz"))
    Cell $cell = Cell.new(str_val => "foo", x_id => "bar", color => Str, border => Str, found => Chip-Symbol.new(num => 1e+101))
    Type check failed in assignment to $!found; expected Common but got Int (42)
      in submethod BUILDALL at test.p6 line 9
      in block  at test.p6 line 28
    

提交回复
热议问题