Hi Peter.

That was a lengthy email and it would be easier for me to simply reply to
all instead of picking specific parts. Unfortunately my email would probably
come out lengthy as well.

I think the examples you gave from Moose were simply to showcase specific
features instead of a proper design. For example, to show how "message"
works. If you want an example of how you would handle an error,
Moose::Unsweetened shows how to handle dates and even emails[1]. They indeed
use a subtype there to do the validation.

I think there are a few flaws in your design, mainly:
1. you're using an object-scoped error indicator (not a good idea!)
2. you're using read-write attributes which add complexity
3. you're pushing the checks yourself instead of letting the code do it
(which also makes the code less self-descriptive)
4. you're not able to make use of lazy attributes because you're forcing it
at build-time

What I would do is:
1. set up a role for each type, just to make it cleaner
(MyApp::Types::Email)[2]
2. create "Email" as a subtype inside that role, and put all the validation
there
3. add coercing abilities to convert other values into email (for example a
string, a scalar reference, a list, etc.)

I'd prefer to have very strict attributes and in case I'm getting the input
in run-time to create the new object, I'd want to add another validation
layer there. Why? Because there are two scenarios to account for:
1. I wrote an object, someone is now using it when they start their app.
They're feeding the CLI to the object, so you don't have a space in which to
put validation - it means it *has to be* in the attribute.
2. I wrote an object, someone is now using it way after they start the app,
and they don't want it to crash everything. In that case, there's a space
where they (or I) can add another validation layer to make sure they don't
create an object with invalid data. In that case the check will be outside
the object, before the object is being constructed and not in the object.

Personally I like objects that blow up when you don't set them up properly.
It ensures no surprises later on.
(and I'm not a try/catch type of guy!)

On a different note, I did have an idea on how to patch Moose in a way that
will allow a user to handle problems whenever they happen via callbacks
instead of crashing everything, but due to time limitations and the fear of
upper scoping changes which isn't possible without continuations (which I'm
not an expert of) make me believe I won't have this pinned down any time
soon. Sorry. :)

[1] https://metacpan.org/module/Moose::Manual::Unsweetened
[2] there are already a few prepared subtypes people have uploaded to CPAN
under MooseX::Types::* - take a look specifically at MooseX::Types::Email (
https://metacpan.org/module/MooseX::Types::Email).
_______________________________________________
Perl mailing list
[email protected]
http://mail.perl.org.il/mailman/listinfo/perl

Reply via email to