I'd like to use Moo as the Object Oriented approach for my app (with a relational database). I had used DBIx::Class & Rose::DB::Object in the past, but these distributions are not Moo (neither Moose) related. I am looking for an ORM (or similar) with a Moo integration, do you know if this exists, or anyone has related plans?
I don't know what do you mean by Moo integration, but I just installed the last version of DBIx::Class and saw that Moo was installed as a dependency. So, in version 0.08209, DBIx::Class has Moo as a dependency
Have a look at DBIx::Mint
You will need to add a role to your Moo classes
with 'DBIx::Mint::Table';
And also write a schema file. This schema file should have all information on classes you're going to use (class-to-table mapping, relationship to other tables/classes). No need to write schema file for each Moo class.
I'm working on something very similar actually - I wanted a Moo-based approach, too. Technically I'm writing it to learn more about Moo, wasn't meant for anything serious, but you might be able to build on it if you wished :-)
https://github.com/bradhaywood/DBIx-Moo
Related
I am trying to use a Perl API that has been written to use the Moose OO system but there is absolutely no inheritance, aggregation, or composition involved between the objects.
And, apart from a single optional role for debugging, there are no roles or mixins involved as well.
As far as I can see at the moment, using Moose just seems to add a massive amount of complication and compile-time overhead for very little benefit.
Why would you use Moose, or OO, as a simple method of encapsulation instead of using the far simpler technique of packaging the code into Perl modules?
Just to clarify, I am totally convinced of the many advantages of using Moose to do OO in Perl correctly and completely. I just don't understand why use OO at all as a simple encapsulation technique? I am not after a subjective argument in favour or otherwise of Perl OO. I am hoping that I am missing some advantage to using the OO paradigm here that I am simply not seeing atm.
This question has an excellent series of points about data encapsulation in Perl. N.B. I am not talking about enforced encapsulation where the system stops you from looking where you shouldn't, more about just only exposing methods in a package that manipulate the data you want to play with.
Is there some advantage to using OO here that I am missing?
Edit 1: After a bit of detective work, I have just seen that the author of the Perl API is also heavily involved in the maintenance and support of the Moose framework.
Edit 2: I have just seen this question which asks a similar thing from a slightly different angle. It's seems like my answer is actually "why would you want to add the complication in the first place?", especially given the info in edit 2 above.
POSSIBLE ANSWER
The API in question seems to be only using the Moose OO system in order to prevent namespace pollution.
This could also be done more than adequately by using Perl packages though, as #amon point out in the comment below, using the standard package mechanism can become cumbersome quite quickly. BTW A big thanks to for all the comments to help clarify what I was asking.
Every situation is diffferent, and whether you choose to use Moose or another object framework (or none at all) really comes down to what you're planning to do and what your requirements are.
There might not be any immediate advantage to writing the system in question with Moose, but consider these:
You get free access to Moose's metaobject system, so you can interrogate the objects for useful information in a well-defined way
You can extend the provided classes using Moose's inheritance system; so even if they don't use inheritance themselves, the framework is already in place for you to do so if needed
You have peace-of-mind because you know the system was built on the most widely-deployed and well-tested object framework for Perl.
People know Moose, meaning there is a higher probability of getting answers to questions if something breaks.
IOW, there is inherent value in using popular tools.
Not sure it's relevant to the API in question, but no-one seems to have mentioned data types yet - that's a big benefit of Moose or Moo, having easily defined and understood (and re-usable) type validation and coercion for attributes.
I'm attempting to create a small ORM library for use in a Mojolicious web-application. I've grown very fond of Ruby's Datamapper library and would like to emulate some of its behaviour if possible.
In Datamapper you can mixin Resource, and then have methods added to your class such as 'all', etc:
# User.rb
class User
include Datamapper::Resource;
end
...
# Application.rb
users = User.all
For my library I'm attempting to add some package level functionality to modules that inherit from a base Model in order to achieve a similar behaviour.
In essence, I would like to be able to do something approximating the following:
# User.pm
package User;
use base Model;
...
# Application.pm
my #users = User::all();
I've had a look around for examples of meta-programming in perl and haven't found anything immediately helpful.
What I'm after is the following:
Alternate perl patterns that achieve similar elegance in a more idiomatic fashion
Ability to inherit subroutines on the package level, as well as the object level
Ability to execute code on 'use' in the scope of the current package, or
Have the current package passed to code that is executed on 'use'
A guide to meta-programming in Perl
A existing declarative ORM library that supports easily creating mock-adapters as well as DB2, and MySQL
Ideally I would like to avoid running eval on large strings as much as possible.
Any help would be greatly appreciated :-)
Alternate perl patterns that achieve similar elegance in a more idiomatic fashion
Roles surpass mixins.
Ability to inherit subroutines on the package level, as well as the object level
Roles are normally consumed on the package level, but with trickery also can be applied to an instance only. (FIXME how?)
Ability to execute code on 'use' in the scope of the current package
import
Have the current package passed to code that is executed on 'use'
All parameters on the use statement are passed into import as arguments.
A guide to meta-programming in Perl
Moose::Manual, Moose::Cookbook
A existing declarative ORM library that supports easily creating mock-adapters as well as DB2, and MySQL
DBIx::Class
Using perl and TAP, I have written a lot of selenium tests and saved them in *.t files.
I have created some helper functions, put them into a non-object oriented package, say My::Util::SeleniumHelper.
All functions are exported from this module.
In the beginning, one package was sufficient, now the single-module API contains quite a few unrelated functions. These functions are called, for example make_sel(),
head_ok(),
cms_logout(),
cms_login(),
cms_clickthru_simple(),
selenium_rc_running(),
treecontrol_toggles() - you get the idea.
Moreover, many blocks of code in the t-files are still redundant, making the .t file look like a template.
Thus, I want to give my *.t code a more OO design.
Any ideas on how to design the new API?
Essentially, I am also looking for code examples (here, or on the internet) where someone has extended the selenium object in a clever way. It does not have to be in perl.
Would it be useful to add methods to the Test::WWW::Selenium object $sel?
$sel->my_click_ok()
I should I try to override the $sel object?, Deriving a Test::WWW::Selenium::Customized class from Test::WWW::Selenium
This would violate the "Prefer composition over inheritance" idiom
Should I wrap the selenium object into another object using composition?
$myobj->{sel}->click_ok()
Here are some more requirements or thoughts:
I also want to use the pageObjects Pattern/Idiom. Not doing so yet.
Maybe so
$myobj->{current_page}->loginbox
or
$myobj->do_stuff($current_page->loginbox)
I noted that in most cases, basically, I'd like to give the selenium method something like an Moose's around() modifier. Do th standard thing, but do some things before and after.
However, I prefer to not use Moose here because the tests need to run on a few different machines, and don't want to install Moose and all its dependencies on all these PCs. I am not saying that is impossible to use moose, however I did not yet use non-moose objects (Test::WWW::Selenium) and moose objects together.
I'm using Moose and delegation to extend Test::WWW::Selenium. The only thing thats in the extension is configuration stuff (host, port, browser, etc). Everything else is in roles.
Making a custom class inheriting from the Selenium one seems completely reasonable in this case. Eric's Moose delegation solution is a little cleaner; but a bit more complicated too.
I'm subclassing Test::WWW::Selenium. new {} needs to call SUPER, but then on, it looks and tastes like the parent. I've got a new open() that lints the HTML and checks links (memoized of course).
It seems strange to me that Perl would allow a package to export symbols into another package's namespace. The exporting package doesn't know if the using package already defined a symbol by the same name, and it certainly can't guarantee that it's the only package exporting a symbol by that name.
A very common problem caused by this is using CGI and LWP::Simple at the same time. Both packages export head() and cause an error. I know, it's easy enough to work around, but that's not the point. You shouldn't have to employ work arounds to use two practically-core Perl libraries.
As far as I can see, the only reason to do this is laziness. You save some key strokes by not typing Foo:: or using an object interface, but is it really worth it?
The practice of exporting all the functions from a module by default is not the recommended one for Perl. You should only export functions if you have a good reason. The recommended practice is to use EXPORT_OK so that the user has to type the name of the required function, like:
use My::Module 'my_function';
Modules from way back when, like LWP::Simple and CGI, were written before this recommendation came in, and it's hard now to alter them to not export things since it would break existing software. I guess the recommendation came about through people noticing problems like that.
Anyway Perl's object-oriented objects or whatever it's called doesn't require you to export anything, and you don't not have to say $foo->, so that part of your question is wrong.
Exporting is a feature. Like every other feature in any language, it can cause problems if you (ab)use it too frequently, or where you shouldn't. It's good when used wisely and bad otherwise, just like any other feature.
Back in the day when there weren't many modules around, it didn't seem like such a bad thing to export things by default. With 15,000 packages on CPAN, however, there are bound to be conflicts and that's unfortunate. However, fixing the modules now might break existing code. Whenever you make a poor interface choice and release it to the public, you're committed to it even if you don't like it.
So, it sucks, but that's the way it is, and there are ways around it.
The exporting package doesn't know if the using package already defined a symbol by the same name, and it certainly can't guarantee that it's the only package exporting a symbol by that name.
If you wanted to, I imagine your import() routine could check, but the default Exporter.pm routine doesn't check (and probably shouldn't, because it's going to get used a lot, and always checking if a name is defined will cause a major slowdown (and if you found a conflict, what is Exporter expected to do?)).
As far as I can see, the only reason to do this is laziness. You save some key strokes by not typing Foo:: or using an object interface, but is it really worth it?
Foo:: isn't so bad, but consider My::Company::Private::Special::Namespace:: - your code will look much cleaner if we just export a few things. Not everything can (or should) be in a top-level namespace.
The exporting mechanism should be used when it makes code cleaner. When namespaces collide, it shouldn't be used, because it obviously isn't making code cleaner, but otherwise I'm a fan of exporting things when requested.
It's not just laziness, and it's not just old modules. Take Moose, "the post-modern object system", and Rose::DB::Object, the object interface to a popular ORM. Both import the meta method into the useing package's symbol table in order to provide features in that module.
It's not really any different than the problem of multiply inheriting from modules that each provide a method of the same name, except that the order of your parentage would decide which version of that method would get called (or you could define your own overridden version that somehow manually folded the features of both parents together).
Personally I'd love to be able to combine Rose::DB::Object with Moose, but it's not that big a deal to work around: one can make a Moose-derived class that “has a” Rose::DB::Object-derived object within it, rather than one that “is a” (i.e., inherits from) Rose::DB::Object.
One of the beautiful things about Perl's "open" packages is that if you aren't crazy about the way a module author designed something, you can change it.
package LWPS;
require LWP::Simple;
for my $sub (#LWP::Simple::EXPORT, #LWP::Simple::EXPORT_OK) {
no strict 'refs';
*$sub = sub {shift; goto &{'LWP::Simple::' . $sub}};
}
package main;
my $page = LWPS->get('http://...');
of course in this case, LWP::Simple::get() would probably be better.
I'm investigating using DbC in our Perl projects, and I'm trying to find the best way to verify contracts in the source (e.g. checking pre/post conditions, invariants, etc.)
Class::Contract was written by Damian Conway and is now maintained by C. Garret Goebel, but it looks like it hasn't been touched in over 8 years.
It looks like what I want to use is Moose, as it seems as though it might offer functionality that could be used for DbC, but I was wondering if anyone had any resources (articles, etc.) on how to go about this, or if there are any helpful modules out there that I haven't been able to find.
Is anyone doing DbC with Perl? Should I just "jump in" to Moose and see what I can get it to do for me?
Moose gives you a lot of the tools (if not all the sugar) to do DbC. Specifically, you can use the before, after and around method hooks (here's some examples) to perform whatever assertions you might want to make on arguments and return values.
As an alternative to "roll your own DbC" you could use a module like MooseX::Method::Signatures or MooseX::Method to take care of validating parameters passed to a subroutine. These modules don't handle the "post" or "invariant" validations that DbC typically provides, however.
EDIT: Motivated by this question, I've hacked together MooseX::Contract and uploaded it to the CPAN. I'd be curious to get feedback on the API as I've never really used DbC first-hand.
Moose is an excellent oo system for perl, and I heartily recommend it for anyone coding objects in perl. You can specify "subtypes" for your class members that will be enforced when set by accessors or constructors (the same system can be used with the Moose::Methods package for functions). If you are coding more than one liners, use Moose;
As for doing DbC, well, might not be the best fit for perl5. It's going to be hard in a language that offers you very few guarantees. Personally, in a lot of dynamic languages, but especially perl, I tend to make my guiding philosophy DRY, and test-driven development.
I would also recommend using Moose.
However as an "alternative" take a look at Sub::Contract.
To quote the author....
Sub::Contract offers a pragmatic way to implement parts of the programming by contract paradigm in Perl.
Sub::Contract is not a design-by-contract framework.
Sub::Contract aims at making it very easy to constrain subroutines input arguments and return values in order to emulate strong typing at runtime.
If you don't need class invariants, I've found the following Perl Hacks book recommendation to be a good solution for some programs. See Smart::Comments.