Showing posts with label perl. Show all posts
Showing posts with label perl. Show all posts

May 3, 2015

Abandoning all Perl modules

As of today I have decided to remove myself as maintainer/comaintainer of all my Perl modules. Feel free to adopt them.

Oct 7, 2014

10 ways of implementing Polymorphism

Firstly what is Polymorphism and why is it so important? Polymorphism is the ability to have a many implementations of a behavior that conform to a single interface. Put in perhaps slightly better, pragmatic terms, you have one implementations of a caller, that can operate on many implementations of a "parameter", without conditionals, or changing the callers code. For instance the following, pseudo?, Perl 6-ism method handler( $obj ) { $obj.execute() }. As you can imagine $obj can be anything that has an execute method. For this Article I'll give you two implementations and one caller, in either Perl 5/6 or Java 7/8, boilerplate will be excluded for brevity.

Inheritance

Single Inheritance

Single inheritance is the most simple and well understood form of Polymorphism.

Multiple Inheritance

Multiple inheritance is often considered dangerous, is unavailable in Java and suffers from the The diamond problem. You should really only use this with a C3 MRO.

Flat Composition

Interfaces

Interfaces are probably the third most common form of Polymorhism, they are essentially codified contracts.

Traits

These are just the same as Interfaces in Java 8 you say? well yes, that's what Java 8 calls them, Traits are a list of methods flattened into a class, but they cannot access state. This basically describes what Java 8 is doing, as you can't access properties from within the interface, well.. at least not unless you do what I show here, which is basically access state through getters and setters.

Mixins

Mixins are basically traits that can access state, though some mixins (AFAIK Ruby) are implemented sneakily as multiple inheritance, rather than flat list composition. IMHO, Mixins should be implemented using flat list composition.

Typeless

Duck Typing

The has $!log in the Mixin is actually a pretty good example of duck typing, we don't check for debug we are just calling it. Java is basically incapable of doing this, except, you can treat everything as an Object (if that's all you need).

Function References

references to functions may or may not be allowed to have varied signatures depending on the language, but so long as they have the same signature they are interchangeable, and thus polymorphic. So why aren't normal functions (procedures), for example, Polymormphic, the problem with procedures is that you have to import the implementation from outside the file, where with polymorphic code, you can create your instance outside the file, pass it into code that's in the file, without changing the code, pass in a different implementation, and it'll continue to work. To modify procedural code, you'd have to modify at least the import, and in compiled code that means a rebuild. It's worth noting these aren't so much typeless as their is only one type to be concerned with, a function.

Miscellaneous

I'm personally skeptical of whether these actually fit the definition of Polymorphism, but they sort of do, just in completely different ways from the above

Method Overloading

Method overloading is called ad hoc polymorphism and is kind of weird in that what it's really doing is hiding the type change from the programmer. Reality is you're kind of asking for different behavior, but you want to hide that it's different in the caller. However since it means you wouldn't have to change the caller, it counts.

Generics

I describe generics as class templates, because they remind me of having an HTML template, and then filling in the blanks by passing in variables, the variable happens to be a Type. Perl doesn't have Generics, and I'm not aware of plans for it in Perl 6.

Reflection

Reflection is sort of polymorphic in that you can essentially treat all objects the same, via a single standard API. I don't know that I want to show the kind of Reflective code because it get's real complicated fast, but for example, @Inject can be annotated in systems with CDI compliant injector, they will reflectivly treat all objects with this the same, and then set the annotated property.

Jul 1, 2014

Writing deprecation notices in perl, optionally with Moose

Sometimes you want to remove behavior from your code in a future version, here's the right way to do it.

Here's the quick of how it works, the before has to come after attributes because the methods aren't yet created. Using before also means it'll always run with your method, without actually touching your method, insuring no accidental consequences to your method. The @CARP_NOT ensures that the warning thrown doesn't show a line number in your package, or from within where Method Modifiers are actually run. warnings::warnif( 'deprecated', ensures that these warnings are only emitted if you have the deprecated category enabled. But what if people don't have warnings enabled? um... oh well? that's there problem because what if people do and they want to silence these until they can get to them. I highly suggest putting the name of the method being called and it's successor into the message so that people know how to correct their code.

If you don't want Moose, just don't use the method modifier and put warnings:warnif directly in your code. if you're using a different AOP before, modify @CARP_NOT to have the correct module.

Mar 13, 2014

Matching Hex characters in a Regex

I've noticed a common problem with regular expressions and Hex Characters, so I thought I'd blog about it. The most common way to regex a UUID, or SHA1 or some other hex encoded binary value is this (and I've seen this in Perl libraries and StackOverflow answers).

[a-f0-9] or [A-F0-9]

Neither of these are correct as Hex is case insensitive and both of these regex's are. Hex is most commonly lowercase (unless you're Data::UUID), but that's an aesthetic, not a requirement. The best way to match Hex is using a POSIX character class.

[[:xdigit:]] or \x

which matches this in a more readable manner, and intent driven manner

[A-Fa-f0-9]

as a side note it's this in a regex string in Java

"\\p{XDigit}"

Feb 27, 2014

The ShareDir Problem

Some of you may have noticed a while back that converted Pod::Spell to the use of File::ShareDir::ProjectDistDir instead of keeping the wordlist in Pod::Wordlist::__DATA__. This move was made in conjunction with making Pod::Wordlist an Object, and in preparation for a time when you'll be able to specify your own wordlist file. It was also made so that non technical contributors could more easily update the wordlist without going near anything that looked like code.

So why shouldn't you put them in __DATA__? According to File::ShareDir

Quite often you want or need your Perl module (CPAN or otherwise) to have access to a large amount of read-only data that is stored on the file-system at run-time. On a linux-like system, this would be in a place such as /usr/share, however Perl runs on a wide variety of different systems, and so the use of any one location is unreliable. Perl provides a little-known method for doing this, but almost nobody is aware that it exists. As a result, module authors often go through some very strange ways to make the data available to their code.

The most common of these is to dump the data out to an enormous Perl data structure and save it into the module itself. The result are enormous multi-megabyte .pm files that chew up a lot of memory needlessly.

Another method is to put the data "file" after the __DATA__ compiler tag and limit yourself to access as a filehandle.

The problem to solve is really quite simple.

1. Write the data files to the system at install time.
 
2. Know where you put them at run-time.

Knowing where you put them at run-time is actually still a problem, because, we don't develop in the same spot that perl installs stuff. The first portion of the problem is, "my tests can't find my sharedir file". So Test::File::ShareDir, which overrides the File::ShareDir method. People say, use Test::File::ShareDir, it solves the pain, well that's not true, they're missing a different pain. What happens if you're trying to run, say bin/podspell from the git directory? oh right now it can't find the sharedir file again. In that case I could probably work around it, but it's a mild symptom of a greater problem I've encountered, people aren't deploying CPAN modules, they're deploying from git. Now I could say, "not supported", but unfortunately I'd usually have to say that to my current boss, or coworker, whomever that may be (and I tried it, didn't work). This isn't actually the root of the problem with Pod::Spell, but I guarantee it was a problem with Business::CyberSource. Mostly I feel like leaving Pod::Spell this way is helping to weed out the issues people will have with File::ShareDir::ProjectDistDir

So what do I think the solution is? There are obviously numerous "social" problems here, that I don't think can be easily solved. I'm sure that Kent Fredric, has a better grasp than I of the technical solutions. Though I have had one reoccurring idea which is apparently not tangible without significant effort. Have a searchable sharedir path, like in unix PERL5_SHAREDIR="./share:$DETECTED_DEV_DIR:$PERL5_LIB...", and try looking for the "file in the path" until you find it, then cache that location in memory so you only have to search once per run. This is probably not a good solution for various reasons, or perhaps it's certainly grossly oversimplified in how it could work.

Ultimately, there isn't a good solution right now, and I'm not sure we've actually thought of one.

Nov 2, 2013

Would You Miss Autoderef in 5.20? solutions in search of a problem

This is a response to Chromatics blog post Would You Miss Autoderef in 5.20?, because I can't ever get comments to work on his MT for something like a year (500, or some blogger openid incompat).

In all honesty I don't find either particularly interesting. I've too often been targeting 5.8 or 5.10 for syntax... @{ $foo } is really the most I've ever needed, @$foo is nicer, but beyond that don't need it. I can't figure out the value of either autoderef or postfix deref, neither of these seem to be solving actual pain points, I think perhaps they're a solution in search of a problem. Maybe I just need someone to point out a good use case that this stuff is solving.

Where are the things I actually need? Here's hoping that 5.20 will get method signatures, or exception handling or maybe figure out how to get given/when out of experimental, something useful.

I really do appreciate all the hard work the people who are improving core perl are doing, and it's all needed. Things like __SUB__ and my sub {} are absolutely awesome, as well as all the work on unicode, and other general improvements. Maybe lexical subs will be moved to stable? but I doubt it. Basically I want something that I can point to my friends outside of the echo chamber, something they could look at and say, yeah that's cool, Perl is moving forward.

Oct 23, 2013

Providing with Providers and Bread::Board

So when I started using Dependency Injection the following problem happened, how do I Inject this dependency when the container is not accessible at this point. Ok, that sentence even confused me a little bit, so what do I mean. Let's say I have a Repository for Products that is injected into my controller. Each Product stored has one or more ProductVariants that is part of it's aggregate, which itself has Nested Categories. Loading this entire graph at once would be relatively expensive, so we decide to do some lazy loading via DBI in the classes. One problem, how on earth do we Inject a Database Handle all the way down to Categories. Most of these ways are against DI, but they are solutions to the problem, there are also ways to combine these. Also, your model class having a database handle is probably bad design itself, but I'm not going to get into that. Sadly I've done every one of these

Manual

Well at least you aren't hard coding the way to read your config file, or your database driver. You're smart enough to rely on an Interface rather than an Implementation. This is fraught with so many problems. Firstly if your web server (assuming it's a web application) is getting any kind of traffic at all you'll end up creating tons of database connections, you'll also be reading that config file every time (ok I forget if Config::Merge caches to memory, it might, but often when I see people design this way, they are basically slurping the file every time). Someday 5 years from now, someone is going to hate you because now they need to support replicants... and the config needs to support more connection strings, which means modifying every place you've done this. Also, you've completely lost the ability to inject your dependencies for whatever reason you may want to.

Inheritance/Composition

Ok, this is a little bit better than before, at least now you have Inverted your dependencies, you could provide the config or the database handle to the class. You've also put the code in a centralized place so it's easy to change when you need to. You're still reading the file fairly often, though perhaps less because it now depends on how long Product variant is alive. So what happens if your connection is lost? We still have a connection for each class, a connection that may now be held much longer. Why does Product Variant need access to the config? this is a violation of the Law of Demeter.

Naive Service Locator

We need to get rid of knowledge of the config. We can do this by using a Service Locator, which is simply a well known service to retrieve other services, usually a global singleton. In our example we're at least smart enough to allow ourselves to change the class out via injection for testing. We no longer have tons of connections or config reads. However, we now have a new problems, what happens when our Application Server forks a process and we lose the database connection? What about when our locator gets more complex, like nested containers, that could change or access, specifically with replication. Also our class is now directly dependent on Bread::Board, and its interface. At least we've stopped caring how our database handle is built. Our locator is a global singleton, and we can't change our Container class for testing.

Robust Service Locator

Ok, so this is much better we can now configure which locator instance we use at runtime. We have removed the dependency on the Bread::board interface. There is no longer a problem with database connections being dropped. However, our container is still a global singleton, and our class still knows about it, which again, law of Demeter.

Dependency Injection and Pass it down

For now I've been basically ignoring other classes because with all of these other approaches they aren't really a concern because you would do the same thing in every class, fetch your service. Much of the code is required here anyways, we always would have to do the sql, the transforms the loops. Dependency inversion is the opposite, do not think of how to retrieve the dependency instead have the dependency provided. But this becomes tricky to think of when you're 3 or more levels deep in your hierarchy. One way to do it simply pass the reference. We create a specific problem here, our Repository lifecycle is a singleton so we need to ensure re-connection, thus we must inject the connector which means we are immediately dependent on the DBIx::Connector interface. This doesn't seem that tricky until you add more than one service, which still may not seem that bad, until you have to add one later, and oh my god, now you're modifying several classes.

Dependency Injection with Providers

This next and final sample show's one way of doing this with Providers. A little context on a Provider first, a Provider is simply an object that can be used to retrieve a an instance of an object you need. It's really just a kind of factory, but tends to be specific to dependency injection, in scenarios where you need a new instance of an object each time. It seems that it might also work well for other cases, such as objects with a longer lifespan than a new instance on every request from the injector, but shorter than a permanent singleton. In short a provider should be able to provide you with an instance on request, without requiring to to depend on retrieval.

The code that I'm demonstrating will not work currently practical scenario, meaning one where variant parameters are required. I've opened a bug about resolving the issue. In the mean time, the patch is simple and you could apply it yourself. You could use BUILDARGS to rename an alternate key to the primary hashkey, in your models. You could also just define each model service one at a time instead of looping them, and actually validating their parameters.

You may note that I've removed the config, this was simply so I could build the code out so it works in completion. It maybe advantageous not to put config processing code in the Dependency injector, but rather provide the config to Bread::Board::Declare at the constructor via required services. This way of doing things requires much more code, but is also much more flexible. Every piece of the model, even those hat could not normally be accessed by the injector, can now have it's dependencies injected to it.

Sep 2, 2013

Thinking of presenting at YAPC::NA 2014

So I'm thinking of proposing some talks for YAPC::NA Orlando, and/or maybe do some training. Here's my thought on what I could do that would be a contribution and different from other talks. For Training it might just be a combination of all of the concepts I could do as individual talks. Basically the idea is "I've learned Perl and Moo[se], now how do I build a large application".
  • UML
  • SOLID Object Oriented Design
  • Design Patterns
  • Domain Driven Design
  • Patterns of Application Architecture
  • Service Oriented Architectures, REST, ROA, RPC (including RESTful RPC and Resource Oriented RPC), and Pub/Sub
    • ORM Patterns ( Active Record / Data Mapper / Transaction Script )
    • MVC
    • Layered Architecture
    • Ports and Adapters
  • Dependency Injection ( with Bread::Board )
Let me know your thoughts.

Aug 5, 2013

Pod::Spell maintained but could use more hands

Just before my abrupt departure from my former employer, I took over maintaintership of Pod::Spell. I have started working to clean up the code, add modern and more tests, and improve the wordlist. There is much to be done on this front. More tests are needed yet, to ensure no accidental breakage. There's possibly a unicode bug lurking within Pod::Spell. More words are needed for the wordlist. Patches are welcome as I don't have all the time in the world to work on it.

Jul 6, 2013

Changing default behavior of File::chmod

File::chmod has been around for a long time, and is really stable, and really hasn't changed since 1999. It is far more user friendly than the chmod()  in core Perl. I recently used it for an interview test. It took me a few times to get right however because it's default behavior in symchmod() mode is to use the systems umask. I find this to be very confusing behavior. I actually thought it was a bug at first, and asked for comaint since it hadn't been updated in so long. Now that I realize it's intentional I'm unsure how to best proceed. On one hand I believe that the most obvious behavior (mimicking unix chmod) should be the default, on the other changing something that has been around this long... So I'm writing this blog post. What do you think? should I preserve the behavior? if not I'm aiming for a long deprecation cycle. Unfortunately because it used package variables for this setting, I haven't come up with a way to deprecate code wise that won't be annoying.

Regardless of what I do with this, there'll be a new release that has proper metadata, tests rewritten with Test::More, etc.

May 25, 2013

Moose Interface Pattern with parameter enforcement

Moose interfaces are problematic, for 2 reasons.

1. They are compile time, but runtime features such as attribute delegation could provide the interface (role ordering is the real problem here)
2. They don't ensure anything other than the method name.

I think this problem can be solved better by using around instead of requires Ordering of course still matters here as you can have multiple `around` modifiers on a method. This will throw an exception if method is missing or if the types passed in are not correct.

Jan 3, 2013

Inversion of Control Principle

If you're not familiar with the term "Inversion of Control"( IoC ) or "Dependency Injection" ( DI )you may wish to start with Martin Fowler's post on the subject. If you're looking for a way to do it with Perl, Bread::Board is the way to go. This post however is about the theory behind it, and a path to grokitude if you're finding the concepts challenging. I should advise that I am not yet a buddha on implementation.

What is it?

Now that you're familiar with an understanding of the terms that is not mine (or even if you didn't bother), you may be wondering what I mean by "Inversion of Control Principle", seeing as how we have the Dependency Injection Pattern and Inversion of Control Containers. I'm not sure if anyone actually uses the term "Inversion of Control Principle", though google seems to suggest I am not the first.

The essence of the Inversion of Control Principle is do not attempt to control your code, let its callers control it. Give your caller as much power as you can.

This is of course not a very academic statement

Dependency Inversion

An important piece of the Inversion of Control Principle is the common "Dependency Inversion". It is defined as:

  1. High-level modules should not depend on low-level modules. Both should depend on abstractions.
  2. Abstractions should not depend upon details. Details should depend upon abstractions.
In more laymans terms depend on an interface and not a concrete implementation. For the Perler's. Do not depend on LWP or DBI, but depend on their interface. This is covered more in my post on Interface Driven Design.

Lifecycle Inversion of Control

A second piece of Inversion of Control is do not attempt to control your objects lifecycle. This means, do not enforce a singleton pattern, do not enforce a flyweight pattern, do not enforce an instance. Your objects should be instances always, if you want a singleton put it at the top level of your application or use a Dependency Injection framework to manage the lifecycle. Also package variables that are not constants are evil, they will bite you because they are essentially singletons. Always make your objects instances and let their client code determine their lifecycle.

How do I do it?

Well you don't have to use a fancy IoC/DI framework to do it. Those are simple tools to make life easier after you've designed your software to be consumed by them. To properly invert your control you first start by letting go. Huh? yeah I know.

You start by ensuring that your software has as few concrete dependencies as possible. Like I said you depend on interfaces. Some concrete dependencies are unavoidable, but try to make them uninteresting, or architecturally significant.

With Perl

Start by ensuring that concrete dependencies can be easily replaced at runtime. The easiest way to accomplish this is by allowing them to be passed to your constructor. when using Moose I tend to use lazy loading defaults a lot. Here's an example from cybersource.

sub _build_cybs_wsdl {
    my $self = shift;
 
    my $dir = $self->_production ? 'production' : 'test';
 
    load 'File::ShareDir::ProjectDistDir', 'dist_file';
    return load_class('Path::Class::File')->new(
            dist_file(
                'Business-CyberSource',
                $dir
                . '/'
                . 'CyberSourceTransaction_'
                . $self->cybs_api_version
                . '.wsdl'
            )
        );
}

has cybs_wsdl => (
    required  => 0,
    lazy      => 1,
    is        => 'ro',
    isa       => File,
    builder   => '_build_cybs_wsdl',
);
Although I don't consider it likely that anyone will ever need to use another WSDL for Cybersource, one could easily inject a new Path::Class::File to one when creating the client at the constructor. Another perfect example is the Client itself. It's designed to be useable as a singleton, because I never intend for someone to need to instantiate it twice, however I have not made it a singleton and internally I'm not aware of any code that it actually is treated as such (it appears to usually be instantiated at every request ).

Prefer Class, and Object interfaces to functional ones. Here's some code that demonstrates why.

# this works

use Class::Load 0.20 'load_class';

my $var = 'baz';

my $class = 'Foo::Bar';

my $result = load_class( $class )->class_method( $var ); # works wonders with ->new

# sometimes this will work, but not always. Try this with the various Dumper functions and see which ones work.

use Module::Load 'load';

my $package = 'Foo::Bar';

load $package, 'function';

my $result = function( $var ); # seems to only work if Foo::Bar's exporter works right, many packages have to be exported at compile time not runtime

# perl doesn't like stuff like this or really anything where I've tried substituting the package name into calling a function. at least not with strict on. This is a large reason I'd avoid functional interfaces. They are hard to substitute at runtime. 

load( $package );

my $function = $package . '::' . 'function';

$function->( $var );

I have even better real examples, such as my one in interfaces where I replaced LWP with the AnyEvent::LWP... but unfortunately that code has not been released to the public. The examples given are basically the same principle.

Dependency Injection Frameworks

Dependency Injection Frameworks are not required to use the Inversion of Control Principle they simply make injecting your dependencies and managing lifecycles easier. It also allows you to do concrete class substitution from one place along with deciding that objects lifecyle, and have it's dependencies inserted. When using a DI framework you should strive to call it only once per controller. Though a book that I've read suggests this is Domain Model controller and not an MVC controller, I was unable to make a full distinction.

This example runs particularly slow, probably due to reasons that people hate moose, however, if you remove the loop at the end you'll notice executing one time is about the same as ten, which means that most of this is due to class compiling and loading, actual runtime is fast (or at least, fast enough).

The important thing to pick up is how the Order object requires a payment_gateway that does submit, but it doesn't know how to get that object, or what the implementation will be. Our Dependency Injection framework then simply provides that dependency as needed. It would be trivial to replace our implementation of payment gateway with a different one.

The code is commented, to explain what it's doing where.

Nov 7, 2012

Business::CyberSource API is stabilizing as of 0.7.x

Business::CyberSource (BC) has been going through API changes for a while now. If you're using it you've probably noticed this and wondered why? The reason behind it was when I first made it I wanted it to be extremely simple to use, and I was realistically a Junior programmer. Over the past year I learned a lot about API design and Object Oriented Programming, as well as payment gateways and credit card transaction processing. From the first production ready release I knew that it had design problems due to a large quantity of duplicated code, but at the time I didn't know how to get rid of it.

Domain Driven Design

My first refactor used some principles I learned from Domain-Driven Design: Tackling Complexity in the Heart of Software I changed the design of the objects to be more clear for experts in CyberSource. I also started restructuring them to more closely match the remote model. This meant making Requests and Responses to be made up of nested objects (Responses were only done as of 0.7.x). Another Change regarding this was to rename the submit method to run_transaction which is the name of the Remote Procedure call that is executed.

Composite Design Pattern

By making the Requests up of nested objects it allowed me to use the Composite Pattern from Design Patterns: Elements of Reusable Object-Oriented Software to serialize all of the objects into a simple nested hashref that XML::Compile::SOAP expects. Moving to these smaller objects that could serialize allowed me to also add more offline tests.

Dependency Injection in Tests

Most of the tests for BC start out exactly the same, except for one change, the value in the amount part of the Credit Card Authorization. This is because CyberSource's Test API uses special amounts to allow you to test getting different responses. e.g. something like (I'd have to look it up) 5000.05 is maybe a REJECT with a special processor code and cv code. Because of this I wired up my tests using Bread::Board to reduce the amount of boilerplate code in all tests that require actual remote interaction.

The Impact

Ultimately changing my Remote Facade to make use of more design patterns and be designed after it's niche domain has allowed me to have both simpler, deduplicated, more robust, more correct, and easier to modify code. Some things were not possible in earlier versions, or would have been incredibly complex to add. Now it'll simply be an issue of adding a Moose attribute to add a feature present in the WSDL. Before certain calls could not return all of information that was in the actual SOAP response, now everything should be accessible.

Possible Bugs

One of the possible bugs of this last refactor is that I use MooseX::StrictConstructor for all of my Moose objects. It is possible now that the XML::Compile::SOAP hash is simply passed to the Response Object that if a key I didn't account for were present that an exception would be thrown. If this is thrown on anything other than a 102 Invalid Field response, then it is a bug in BC and should be reported. I could have turned StrictConstructor off on the responses, but I believe that throwing the exceptions may ultimately make BC a better library. Also with a test suite that totals over 1400 (including generated generic ) tests, I'm fairly confident that there will be no problems in production.

New Debugging

In order to aid in finding bugs and diagnosing problems when they happen cybersource now has 2 debug setting levels. These can be set by having debug be 0 (off), 1 (request/response hash), 2 (full soap payloads). These should not be turned on in production and because they will print out Credit Card numbers.

In Trial

Currently I've left BC v0.7.5 in trial, but barring any bugs being reported, or cpan testers tests failing, I'll probably release v.0.7.6 as stable early early next week.

Stable API

I do not forsee any more major API changes in the future of BC, all of my original problems have been weeded out. This means I'll be able to focus on features and documentation with future work. It is possible that some changes to exceptions and error handling may happen, but I don't see that being a big issue.

Nov 3, 2012

Interface Driven Design

What is Interface Driven Design?

Interface Driven Design simply means that you should design your software around a flexible, easy to use, easy to understand interface. This is easy to achieve if your objects are of SOLID design. There is a simple table and reference link if you're not familiar with the principles.

My Work is SOLID already

Then you're on the right track but it's not enough if you don't fully marry the concept to best practices. I've seen quite a bit of work that's SOLID enough but fails to provide good interfaces.

Why is this so important?

Getting your interfaces correct is important because someone should be able to replace your code with new code, or subclassed code and it should still work.

Example: LWP::UserAgent and Mojo::Useragent

These two libraries do exactly the same thing, they provide an HTTP Client. However, they do not conform to the same interface. This means That if you're using Mojolicious to write a web application, but require an external library to interface with a remote API, because its interface will make your development easier, you cannot change it's use of LWP::UserAgent to Mojo::Useragent. Now you've added another dependency and complexity to your application.

Example: DBI

DBI is an example of a common interface to many different database drivers that do similar things, but underlyingly with different syntax. This allows you to use a common interface and ignore the differences in implementation between, say DBD::mysql and DBD::Pg.

How do I get there?

To begin, and as a general rule your interface should conform to style choices in the language you're using. Meaning that in Perl you should use $obj->foo_bar not $obj->getFooBar as it is the style most objects use.

Domain Driven Design

The first thing I suggest doing is design your initial interface using Domain Driven Design. Look at the common language used to describe the thing that you're building, and name your package, classes, methods, functions, after words from the common language. You're writing a new HTTP client? you probably have some concept of POST, so $client->post makes a lot of sense. If you're writing a billing system you may have some concept of Invoice->process. When doing Domain Driven Design your Interface should be easy to understand by an Expert in that domain (regardless of whether they are technically savvy ). Example if I told a Billing expert I was writing the code for Invoice->process they probably would have no idea what the internals meant, but they should easily understand the purpose and a general idea of what it actually does. (note: having an Invoice object might be bad, as an invoice is a request for payment on a Sale, and a receipt is a record of, therefore they are just views on a Sale, but that's a more complex notion)

Pure Fabrication

Unfortunately sometimes what you're creating has no real world equivalent (actually HTTP is an example that is now more of its own domain). So you're making it up as you go. In this case you need to create objects that are a Pure Fabrication. When creating interfaces for these I suggest looking to patterns, simple interfaces, and the interfaces for similar things in other projects, or languages. Use names that are as descriptive as you can get.

Existing Interfaces

You want to do this whenever there is an existing implementation that's not good enough, but has a decent interface. Perfect examples are DBI and LWP. They both have good interfaces, but there's a chance that the implementation isn't good enough (or you have need of a nonexistant driver).

An example with be AnyEvent::HTTP::LWP::UserAgent. If you're using AnyEvent you'll probably know you don't want LWP's blocking interface, but unfortunately the library you need to use uses LWP, what a dilemma. You could rewrite the library entirely to use AnyEvent::HTTP, but this will be both tedious and error prone. However, Anyevent::HTTP::LWP::UserAgent provides an LWP Interface, this means that you can simply substitute it in the library (hopefully the library made this easy by following the Inversion of Control Principle to be discussed in a future post).

Like AnyEvent::HTTP::LWP::UserAgent you may need to build a Facade interface that mimicks another interface. It would be better to start with this interface, but then again sometimes that's not ideal either.

Combinations

Sometimes you have to combine all of these strategies. Business::OnlinePayment::CyberSource (BOPC) and Business::CyberSource ( things I'm responsible for ) are good examples. Business::CyberSource was written because BOPC 2.x was no longer maintained and relied on a proprietary library which was not 64 bit compatible. I decided that I did not like the Business::OnlinePayment interface (and still don't to be honest ) and so set out to create a new one.

My first attempts was in retrospect focussed more on creating a perlish API than a Model driven API. In the long run this caused significant pain and resulted in some bad code. As of version 0.7.x (in TRIAL) Business::CyberSource's API is modeled after the remote API that CyberSource provides, and as such it has become much easier for me to provide access to new remote API features. Because I have continued work on ensuring that my Interface only relies on it's own interfaces it should now be trivial to replace any single piece of Business::CyberSources API. Don't want to use my request objects? you could simply pass an object that can serialize to a hashref that looks like what XML::Compile::SOAP expects. Any Expert at CyberSource should be able to read and understand my API (not tested), where they might not understand BOPC's. Unfortunately to get to this point I've had to break my interface several times.

Later due to new business concerns we had a need to conform to Business::OnlinePayments Interface, and so we rewrote BOPC to use Business::CyberSource as the backend. It does not provide access to all of the features, but it can be used in anything that knows how to use a Business::OnlinePayment API. I would have preferred to have this done sooner, but due to tuits and business constraints it was put off.

If you read the Source of either of these you will find a few fabrications, such as the use of Factories.

Interface as a Language Feature

Many languages support specifying the interface via a language feature. If your language supports this you should take advantage of it. Unfortunately Perl's simple can support really isn't enough, and Moose's Interface as Role support doesn't really work due to ordering issues. (I implemented the interface but unfortunately due to ordering my implementation is runtime and happens comes after the compiletime requirement ). I will say though that I believe it is more important to provide the actual calling convention in a dynamic language like Perl, than use of an actual interface. At least with Moose I feel that an interface is (generally) as concrete as the isa for the class, and so I don't bother checking them, they are an implementation detail.

Conclusion

Ultimately the goal is to create easy interfaces to understand, use, and properly reflective of the problem. By doing so you also make concrete implementations easy to update and reuse without breaking your clients.

Jun 11, 2012

Perl Core Syntax Wishlist: Role Support

I want to see Role's added, even PHP got Traits before Perl. It doesn't have to be a huge thing, in fact all I want is the composition aspect. Let me do this: I don't really want or need anything else right now, just that would be fine. We should have interfaces too, but they aren't really required just to support Role's. We should probably have some sugar like I did for class (e.g. role keyword. and some of the same modules/pragmas loaded for this too)

Jun 4, 2012

New Module: MooseX::RemoteHelper (RFC)

Background

I have spent much of the last year writing and refining Remote Facades. At this point I've worked with SOAP, REST/JSON, and RPC url-form-encoded API's. One of the hardest parts I've found is dealing with the serialization of a Data Transfer Object with a Perl interface into whatever the remote is expecting. When I started I didn't know of these patterns, or really anything about these patterns. I highly recommend reading Patterns of Enterprise Application Architecture) if you want to know more about these patterns or things like Active Record and MVC.

problem

The problems I've encountered are many, including the fact most remotes are buggy or have a cludgy interface. Though there's nothing you can do about a remote api that you don't control, you can make your local API much cleaner and more native. Doing this however comes with a few challenges. One is that you have to map a local attribute name to a remote attribute name, because Perl uses underscores, and Java uses camel case, e.g postal_code and postalCode. The second problem is that many times the value of the attribute in its perl native form is not what the remote wants, e.g. perl boolean "1" remote "Y", or a DateTime object to W3C formatting. This second is not quite the same as mapping, because mapping is one to one, this translation could be turning an array into a comma separated string. The third problem, I didn't run into until after I "solved" the first , is how should I deal with nested complex objects (one's that can't be just converted to just a string).

My first naive remote facade was very procedural and simply assembled top to bottom, in part because it was based on SOAP::Lite, and in part because I had yet to figure out a better way. This resulted in a giant unwieldy if/then chain. Obviously my translations were just inline too.

The next thing I tried was using triggers to construct a request hash to pass to XML::Compile::SOAP. This worked better as the hash constructing code was kept right next to the attribute, so if I needed to modify the local or remote attribute, I could just go look at the attribute and the trigger tied to it.

After that I tried to use a map to translate from the native attribute name to the remote attribute name. This may have been more successful had it worked more like the Assembler in the Remote Facade. But ult imately since we were developing a rapidly changing API it seemed to bog me down, this is because I was changing the attributes on both sides of the mapping and thus the mapping at the same time (so at least 3 places). Here I was just manually dealing with the translation from a W3C DateTime format to the object I needed.

a solution

When I got assigned to yet another API and found myself doing yet another mapping and translation I decided that I needed to solve the problem. Enter the first iteration of MooseX::RemoteHelper. The first tie I used it with the form-url-encoded API so it was only needed for a single level of key, value pairs. .

Once I determined how to create MX::RemoteHelper it was simply a matter of using Class::MOP::Class API's to iterate all the attributes. The source of CompositeSerialization will give you some idea of how I did this.

Then I went back to apply this to a previous module, because the technique appears to be cleaner. Unfortunately I ran into a problem, this other API was a complex data structure, and how best to provide nested hashrefs and arrayrefs. Though I was now armed with Patterns I didn't know of one that would solve the problem. Fortunately a quick flip through the Gang of Four brought me to the Composite Pattern. I used this to write the recursive CompositeSerialization so that if I had a sufficiently complex nested structure I could simply create another object to deal with that. Here's a full example:

use 5.014;
use warnings;
use Data::Dumper;

package MessagePart {
    use Moose;
    use MooseX::RemoteHelper;
    with 'MooseX::RemoteHelper::CompositeSerialization';

    has array => (
        remote_name => 'SomeColonDelimitedArray',
        isa      => 'ArrayRef',
        is        => 'ro',
        serializer => sub {
            my ( $attr, $instance ) = @_;
            return join( ':', @{ $attr->get_value( $instance ) } );
        },
    );

    __PACKAGE__->meta->make_immutable;
}
    
package Message {
    use Moose;
    use MooseX::RemoteHelper;

    with 'MooseX::RemoteHelper::CompositeSerialization';

    has bool => (
        remote_name => 'Boolean',
        isa      => 'Bool',
        is        => 'ro',
        serializer => sub {
            my ( $attr, $instance ) = @_;
            return $attr->get_value( $instance ) ? 'Y' : 'N';
        },

    );

    has foo_bar => (
        remote_name => 'FooBar',
        isa      => 'Str',
        is        => 'ro',
    );

    has part => (
        isa      => 'MessagePart',
        remote_name => 'MyMessagePart',
        is        => 'ro',
    );

    __PACKAGE__->meta->make_immutable;
}

my $message
= Message->new({
    bool    => 0,
    foo_bar => 'Baz',
    part    => MessagePart->new({ array => [ qw( 1 2 3 4 ) ] }),
});

say Dumper $message->serialize

Which should give you this data structure:

Request For Comment

I've recently released a Trial version of MooseX::RemoteHelper to CPAN. I'm currently refactoring Business::CyberSource to use it, and it appears to be solid. What I'd like to know what people think of the module names, method names and any other comments they might have. I haven't been entirely sure that I've been naming things correctly while writing this, or that the code couldn't be better in other ways. If there's functionality you wish it had but doesn't let me know.

May 28, 2012

Perl Core Syntax Wishlist: Class support

I would like to see the class keyword become part of Perl, but unlike some I don't want it simply because it's nicer syntax. I'd like it to behave differently from package. I'd basically like to see this I'm sure smarter people than I could think of a few more things that might be nice to have by default in all classes. I would like to note that method signatures is not that big of a deal to me, unless of course you want to give me named variables in the signature besides just auto shifting off self, e.g. method foo ( $bar ) { return $self->{foo} if $bar }

May 21, 2012

Better Exceptions with Exception::Base

So I've done some complaining and explaining about what I'd like to see in regards to Exceptions in Perl. I Mostly explained what I wanted for catching Exceptions, and a little on throwing Exception objects, but not really how those objects should behave. I've looked at and tried various exception modules, including croak, confess, and Throwable. I basically spent time one day reading the manuals of most of the exception objects on CPAN. Most of them didn't allow me to easily for the exceptions I needed (meaning they required more work than I thought I should do for one or two exceptions ). Among these modules I found Exception::Base, which appears to do everything I need (though I still wish for something like it in core, with shinier syntax). Of course wee need to be able to throw simple Exceptions, preferably ones that can stringify, and are easily matched in a switch or if statement. Exception::Base can do all of that, and it even boolifies to true. A really big thing I wanted was a class I could easily add attributes to without writing a whole new package/pm and subclassing it there. I wanted this because I really wanted to be able to have 2 kinds of messages, one for programmers, and one for users, but truthfully I only had one class where I needed this flexibility (at the time). It is also occasionally useful to have attributes that describe something, e.g. would be really useful in moose attribute exceptions, to be able to have an object where you could catch the exception and get the attribute name without parsing. Fortunately Exception::Base can do this too. You'll notice if you run this script that in the warn, both usermsg and logmsg are printed because they are both string_attributes. You'll also notice that attr isn't printed at all, but that we can look at it directly to make other decisions. Exception::Base has other features such as setting the verbosity so you can go from a croak level message to a full stacktrace. It also allows you to ignore_packages so that the exception does not appear to be thrown from that package. This is similar to @CARP_NOT.

May 14, 2012

Perl Core Syntax Wishlist: die should die

I hate die it is, in my humble opinion, one of the worst parts of perl. I really wish it would be deprecated, and removed, or at least replaced with something that would tell you were the code that was die-ing was being called. Replace its implementation with that of Carp's croak or confess and I'd be happy. Better yet, let's just get real exception support and deprecate die (even if that's never removed deprecation just make that real big on its pod). If you're using die please stop and use Carp, anyone using your module will thank (and by thank I mean not curse) you later.

May 7, 2012

Perl Core Syntax Wishlist: an Exception Stack

I have come to wish many things were part of Perl syntax that are not, and no using external modules is not enough for me. I think it's time Perl got the features as part of the language itself (and yes I suppose I could settle for feature.pm, and no I'm probably not going to write them myself, I'm not smart enough yet). The first of these is a proper exception stack. I want to be able to write: I think we need throw, try, catch, and finally keywords. And no I don't think it makes sense to have Object->throw. In fact I think this Original Perl 6 Syntax Proposal reads like just what we need in Perl 5. Unfortunately I think this is what we are getting in Perl 6, which IMO is not as nice.