Created
April 8, 2015 14:53
-
-
Save skids/cf9065039903df5047ac to your computer and use it in GitHub Desktop.
preview_of_x_protocol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
=NAME X::Protocol - Perl6 Exception superclass for protocol result codes | |
=begin SYNOPSIS | |
=begin code | |
# A simple example for a protocol that just has error codes | |
class X::Protocol::SneakerNet is X::Protocol { | |
method protocol { "SneakerNet" } | |
} | |
my @errors = X::Protocol::SneakerNet.new(:code(10)), | |
X::Protocol::SneakerNet.new(:code("11")), | |
X::Protocol::SneakerNet.new(:code("12.5")), | |
X::Protocol::SneakerNet.new(:code("13W")), | |
X::Protocol::SneakerNet.new(:code("XL")), | |
X::Protocol::SneakerNet.new(:code("XXL")); | |
# A default .Numeric and .Str are provided based on :code, | |
# so you can handle the above errors like this: | |
for @errors { | |
when 10 { say "Matches the first one" } | |
when 11 { say "Matches the second one" } | |
when 12.5 { say "Matches the third one" } | |
when "13W" { say "Matches the fourth one" } | |
when /XL/ { say "Matches the fifth and sixth one" } | |
} | |
# You can add human readable "code-message" method and specify | |
# a "severity" method. You may also define your own "toss" | |
# method to perform a throw or fail only when appropriate. | |
# | |
# By default, .severity is always "error", and .toss | |
# calls .fail when .severity is "failure" and .throw when | |
# .severity is "error", and note(.gist) when severity | |
# is "warning". | |
# | |
class X::Protocol::IPoUSPO is X::Protocol { | |
method protocol { "IPoUSPO" } | |
method code-message { | |
given self.code { | |
when 500 { "Chased away by dog" } | |
when 400 { "A snowy, rainy, hot and gloomy night" } | |
when 200 { "Delivered" } | |
} | |
} | |
method severity { ~$.code ~~ /\d/ // "unknown" } | |
method toss { | |
if self.severity > 4 { self.fail } | |
elsif self.severity > 2 { self.throw } | |
else { note self.gist } | |
} | |
} | |
# The default message shows the protocol, severity, code, and code-message | |
X::Protocol::IPoUSPO.new(:200code).say; # IPoUSPO 2: 200 -- Delivered | |
# Remember .Str is just the stringified code; | |
print X::Protocol::IPoUSPO.new(:400code), "\n"; # 400 | |
# For one-offs you can supply a per-instance protocol name | |
{ | |
X::Protocol.new(:404code :protocol<HTTP>).toss; | |
"HERE".say; # gets here, because default "error" gets resumably thrown | |
CATCH { | |
$_.resume; | |
} | |
} | |
=end code | |
=end SYNOPSIS | |
=begin DESCRIPTION | |
=end DESCRIPTION | |
class X::Protocol is Exception { | |
has $.code = "ad-hoc"; | |
has Str $.protocol = self.protocol; | |
method protocol { | |
die "A protocol name is required" unless $!protocol; | |
$!protocol; | |
} | |
method message { | |
join(" -- ", | |
$!protocol ~ " " ~ self.severity ~ ": $.code", | |
self.code-message); | |
} | |
method code-message { () } | |
method severity { "error" } | |
method Numeric { | |
+$.code // NaN; | |
} | |
method toss { | |
given self.severity { | |
when "failure" { self.fail } | |
when "error" { self.throw } | |
when "warning" { note(self.gist) } | |
default { } | |
} | |
} | |
method Str { | |
~$.code // ""; | |
} | |
# Without this we get an error about not being able to create a | |
# backtrace in .gist. Yet, even with this, we still get backtraces | |
# on uncaught failures. | |
# method gist { self.message ~ (self.backtrace.defined)} | |
} | |
=AUTHOR Brian S. Julin | |
=COPYRIGHT Copyright (c) 2015 Brian S. Julin. All rights reserved. | |
=begin LICENSE | |
This program is free software; you can redistribute it and/or modify | |
it under the terms of the Perl Artistic License 2.0. | |
=end LICENSE | |
=SEE-ALSO C<Exception> | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment