2017-03-28 1 views
5

저는 대학에서 화학을 연구 중이며 Perl6 또는 Perl에서 화학 공식이나 다른 프로세스의 균형을 조정하는 등의 교과서 예제를 작성하려고합니다!Perl 6 사용자 지정 연산자 사용

그런 다음 perl6 사용자 지정 연산자에 문제가 발생했습니다. 이 기능을 사용할 때 코드와 본인을 반복하고 있다고 느낍니다. 읽기 및 쓰기가 어렵습니다. 어떻게 이것을 단순화 할 수 있습니까?

#!/usr/bin/env perl6 
use v6; 
#basic SI(International System of Units) type 


role MetricPrefix { 
    method baseOn (Str $base , Numeric $input) { 
     given $base { 
      when 'pico' { return $input * 10**-12 } 
      when 'namo' { return $input * 10**-9 } 
      when 'micro' { return $input * 10**-6} 
      when 'milli' { return $input * 10**-3 } 
      when 'centi' { return $input * 10**-2 } 
      when 'hecto' { return $input * 10**2 } 
      when 'kilo' { return $input * 10**3 } 
      when 'mega' { return $input * 10**6 } 
      when 'giga' { return $input * 10**9 } 
      when 'tera' { return $input * 10**12 } 
      default { fail "you must input a metric prefix which allow pico to tera" } 
     } 
    } 
} 



class Mass does MetricPrefix { 
    #basic Mass is g is different form si statda 
    has $.g; 

    submethod BUILD (:$!g ) { 
    } 

} 

class Length does MetricPrefix { 
    has $.Length ; 

    submethod BUILD (:$!Length ) { 
    } 
} 



multi postfix:<(kg)>($input) { 
    return Mass.new(g => Mass.baseOn("kilo",$input)) or fail "you Must input a number"; 
} 

multi postfix:<(g)>($input) { 
    return Mass.new(g => $input) or fail "you Must input a number"; 
} 

multi infix:<+>(Mass $inputOne , Mass $inputTwo) is assoc<right> { 
    return Mass.new(g => $inputOne.g + $inputTwo.g) or fail "error in there "; 
} 

multi infix:<->(Mass $inputOne , Mass $inputTwo) is assoc<right> { 
    return Mass.new(g => $inputOne.g - $inputTwo.g) or fail "error in there "; 
} 

multi infix:<*>(Mass $inputOne , Mass $inputTwo) is assoc<right> is tighter(&infix:<+>) is tighter(&infix:<->) is tighter(&infix:</>) { 
    return Mass.new(g => $inputOne.g * $inputTwo.g) or fail "error in there "; 
} 

multi infix:</>(Mass $inputOne , Mass $inputTwo) is assoc<right> is tighter(&infix:<+>) is tighter(&infix:<->) { 
    return Mass.new(g => $inputOne.g/$inputTwo.g) or fail "error in there "; 
} 





#the meterLeng 
multi postfix:<(km)>($input) { 
    return Length.new(Length => Length.baseOn("kilo",$input)) or fail "you Must input a number"; 
} 

multi postfix:<(m)>($input) { 
    return Length.new(Length => $input) or fail "you Must input a number"; 
} 

multi infix:<+>(Length $inputOne , Length $inputTwo) is assoc<right> { 
    return Length.new(Length => $inputOne.Length + $inputTwo.Length) or fail "error in there "; 
} 

multi infix:<->(Length $inputOne , Length $inputTwo) is assoc<right> { 
    return Length.new(Length => $inputOne.Length - $inputTwo.Length) or fail "error in there "; 
} 

multi infix:<*>(Length $inputOne , Length $inputTwo) is assoc<right> is tighter(&infix:<+>) is tighter(&infix:<->) is tighter(&infix:</>) { 
    return Length.new(Length => $inputOne.Length * $inputTwo.Length) or fail "error in there "; 
} 

multi infix:</>(Length $inputOne , Length $inputTwo) is assoc<right> is tighter(&infix:<+>) is tighter(&infix:<->) { 
    return Length.new(Length => $inputOne.Length/$inputTwo.Length) or fail "error in there "; 
} 


#just a test 
say 10(kg) + 1(g); 
say 10(m) + 1(m); 
+2

해결해야 할 문제가 아닌 코드 검토 질문과 같습니다. 자매 사이트 인 https://codereview.stackexchange.com – IMSoP

+0

에 더 잘 맞는 것으로 사용자가 알아보고 (도움말 센터를 먼저 확인하십시오.) 속성을 공개로 선언했기 때문에 'submethod BUILD'는 필요하지 않습니다. –

+0

예, 이 submethod BUILD는 객체 생성을 사용하지 않았을 때 불필요합니다. –

답변

2

필자는 오류 메시지를 입력의 선언 유형으로 바꿨습니다. 그러면 Perl 6은 숫자가 입력되는지 여부에 대해 걱정할 것이며, 그렇지 않은 경우 적절한 오류 메시지를 제공합니다. 나는 또한 모든 길이와 질량이 양수라는 가정하에 만들었다.

#!/usr/bin/env perl6 
use v6; 
#basic SI(International System of Units) type 

role MetricPrefix { 
    method baseOn (Str $base , Numeric $input) { 
     given $base { 
      when 'pico' { return $input * 10**-12 } 
      when 'namo' { return $input * 10**-9 } 
      when 'micro' { return $input * 10**-6 } 
      when 'milli' { return $input * 10**-3 } 
      when 'centi' { return $input * 10**-2 } 
      when 'hecto' { return $input * 10**2 } 
      when 'kilo' { return $input * 10**3 } 
      when 'mega' { return $input * 10**6 } 
      when 'giga' { return $input * 10**9 } 
      when 'tera' { return $input * 10**12 } 
      default { fail "you must input a metric prefix within the range of pico to tera" } 
     } 
    } 
} 

class Mass does MetricPrefix { 
    #basic Mass is g is different form si statda 
    has $.g where * > 0; 
} 

class Length does MetricPrefix { 
    has $.Length where * > 0; 
} 

# Mass 
multi postfix:<(kg)>($input where * > 0) { 
    return Mass.new(g => Mass.baseOn("kilo",$input)); 
} 

multi postfix:<(g)>($input where * > 0) { 
    return Mass.new(g => $input); 
} 

multi infix:<+>(Mass $inputOne , Mass $inputTwo) is assoc<right> { 
    return Mass.new(g => $inputOne.g + $inputTwo.g); 
} 

multi infix:<->(Mass $inputOne , Mass $inputTwo) is assoc<right> { 
    return Mass.new(g => $inputOne.g - $inputTwo.g); 
} 

multi infix:<*>(Mass $inputOne , Mass $inputTwo) is assoc<right> is tighter(&infix:<+>) is tighter(&infix:<->) is tighter(&infix:</>) { 
    return Mass.new(g => $inputOne.g * $inputTwo.g); 
} 

multi infix:</>(Mass $inputOne , Mass $inputTwo) is assoc<right> is tighter(&infix:<+>) is tighter(&infix:<->) { 
    return Mass.new(g => $inputOne.g/$inputTwo.g); 
} 

#Length 
multi postfix:<(km)>($input where * > 0) { 
    return Length.new(Length => Length.baseOn("kilo",$input)); 
} 

multi postfix:<(m)>($input where * > 0) { 
    return Length.new(Length => $input); 
} 

multi infix:<+>(Length $inputOne , Length $inputTwo) is assoc<right> { 
    return Length.new(Length => $inputOne.Length + $inputTwo.Length); 
} 

multi infix:<->(Length $inputOne , Length $inputTwo) is assoc<right> { 
    return Length.new(Length => $inputOne.Length - $inputTwo.Length); 
} 

multi infix:<*>(Length $inputOne , Length $inputTwo) is assoc<right> is tighter(&infix:<+>) is tighter(&infix:<->) is tighter(&infix:</>) { 
    return Length.new(Length => $inputOne.Length * $inputTwo.Length); 
} 

multi infix:</>(Length $inputOne , Length $inputTwo) is assoc<right> is tighter(&infix:<+>) is tighter(&infix:<->) { 
    return Length.new(Length => $inputOne.Length/$inputTwo.Length); 
} 


#just a test 
say 10(kg) + 1(g); 
say 10(m) + 1(m);