Dec 1, 2013
Advent, good idea, but problematic execution
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
- 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 )
Aug 5, 2013
Pod::Spell maintained but could use more hands
Jul 6, 2013
Changing default behavior of File::chmod
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
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:
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.
- High-level modules should not depend on low-level modules. Both should depend on abstractions.
- Abstractions should not depend upon details. Details should depend upon abstractions.
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. 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.
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.