Saturday, November 24, 2012

TD e-Series Post Follow Up

This post got me some personal attention from TD after I posted a link on Twitter. Their social game is pretty good. They ask me for some contact info and after a few days someone in the e-Series group contacted me. She was very nice and we had a chat about the process as it stands and how it could be better.

It turns out I used the wrong form altogether. The 11 page one that I've spent so much time on is for opening a new account. There is a much shorter one for converting an existing account. Big, big sigh. I'm really not sure how I missed that. Now that I go looking for the forms I see that there is always a link for both cases. Maybe having not worked at CIBC since February my form-fu has gotten rusty.

According to the person I spoke to, there are a couple of interesting reasons TD doesn't offer the e-Series index mutual funds on all mutual funds, making the extra steps necessary:
  • Due to mutual fund regulations enforced by the Mutual Fund Dealers Association these funds shouldn't be offered by fund advisers due to their "do it yourself" nature. I'm not totally convinced this is a major factor because TD, like the other banks, offer a range of index funds through advisers, but with higher management expense ratios (MERs).
  • Fund advisers get commissions from selling mutual funds, which is why even normal index funds have surprisingly high MERs. They can't sell the e-Series because there is no compensation structure, hence the lower MERs. To me, this is the primary reason.
I made a few suggestions about the process, like somehow pre-filling the forms with information after you've logged in to online banking. Another was to just make the e-Series funds available to everyone all the time. I understand that they can't be sold through a branch, but I'm not sure what would prevent making them available to everyone online only, I didn't ask. Perhaps some compensation happens even when you buy mutual funds online that needs to change.

I'm happy that someone from TD listened to my suggestions, and seemed to understand that the process could be better. She offered to help speed up the process by having me fax the forms to her, which is very nice. But I still have a bit of a bad taste left in my mouth having had to try this 3 times for the same account. It's made me very curious about potential alternatives.

All Canadian banks suffer from process problems. So far President's Choice Financial has been the lowest friction one I've dealt with, because of their online nature. If ever foreign banks are allowed to  compete seriously in Canada the current banks will have to adapt very quickly. Things still feel like they're stuck in a time before the internet.

Friday, November 23, 2012

My Investment Plan - Index and Ignore

The last few times I've set up investment accounts at TD I've had to sit through their "Investor Profile" quiz. I imagine most banks do this, too. They ask you a series of questions to see if how you think of yourself in terms of investing matches how you'd react to certain situations. For example, if you say you want a highly risky, all-stocks portfolio, but couldn't stomach a 5% loss in a year, then you're inconsistent. If you are consistent then they will recommend a portfolio that better matches your true risk tolerance.

However, if your plan is to stick to a certain asset allocation year after year, not changing it for any reason, they have no clear way to accommodate you. As I recall it, there is yet another form that explicitly absolves them of any differences between your answers and what you do with your money. It's all about identifying potential liabilities in the form of people whose portfolios don't match their risk tolerance. The assumption is that everyone needs help investing from the mutual fund salesperson. Oh, did you not realize everyone in the branch is a salesperson, including the tellers? Opening an account gets someone some money, and getting you into specific mutual funds is very valuable.


Doctors don't scan your thyroid for potential cancer activity because there is so much weird stuff in thyroids that there's no point in acting on the findings. And so it goes for index investing. My plan is to follow a strategy of investing in very low cost index funds, rebalancing to a particular asset allocation yearly with a net deposit. This is called couch potato portfolio investing because it involves so little effort. I pay no attention to what's going on with my money because there is no information on which I would act. Up 15%? Whatever. Down 30%? Don't care. (Actually, if I knew this I'd pile in more money because it's like stuff's on sale.) Index investing addresses the two biggest impacts to investing: 1. the fees in the form of the management expense ration (MER) and 2. the damage done by investors selling when things are low and buying when things are high.

As a math geek I can envision myself tracking the daily value and yearly return of my (still small) portfolio, just because I know how. However, the information is as meaningless to me as the standings in the NFL. I'm happy to let that which doesn't matter truly slide, as Tyler Durden does.

Sunday, November 18, 2012

A Letter to TD Canada Trust on their Abysmal e-Series Application Process



I recently applied to be able to buy TD's e-Series mutual funds in my daughter's RESP account. These are index mutual funds with very low expense ratios, and are a great alternative to exchange traded index funds for small portfolios.

I've been through the process 3 previous times with our other investing accounts (2 RRSPs, son's RESP). It's ridiculous, and getting more so every year. You go to a branch, fill in forms, answer questions and they open your new mutual fund account. Except you can't access the e-Series yet. You have to fill out something that looks just like a new mutual fund account application. It's really not obvious that this will result in the funds being available for purchase in your existing fund account.

TD sent my application back because of some missing information, so I'm including this note with my response. At least they sent a prepaid envelope in which to return it.


To Whom It May Concern:

You, TD Canada Trust, have made the process of being able to buy your e-Series index mutual funds in an existing account about as hard as possible. There is no reason to require so much information that you already have. You already know my and my wife’s name, employment information, SINs, banking information, and investment profiles. We gave it when we opened the mutual fund accounts that we already own. Another bank is going to create a very similar line of products, put a simple sign up process in front of it and will eat your lunch, if they haven’t already. I just want the funds to appear in the drop down list on the website. Why does it require 11 pages of documentation? It verges on the level of a tax return. And I can file that online!

This is the fourth time we have been through this ridiculous process, but it has never been this bad. I will not forget this experience. I will have a hard time recommending the e-Series funds to others because of it. MoneySense magazine often recommends them, but I will be writing a letter to the editor to let them know just how onerous you have made the process. I plan to research alternatives to these mutual funds for my future investing needs.

Sincerely,

James McLachlan

Saturday, April 28, 2012

Running Tests, Boodhoo Style

Watch this and weep at the beauty of Jean-Paul Boodhoo’s development environment.  In particular marvel at the whole “saving a file causes compilation, runs tests and lists failures in a toast pop-up” thing.  WANT.
JP publishes everything you see in the dnrTV episodes on github, so we can all learn.  He recorded a webinar about his setup, but hasn’t published the video yet.  I couldn’t wait so I went digging.
At the core is a Ruby script that checks every second for updated files and runs msbuild  to compile and then the MSpec test runner.  The script parses the MSpec runner’s output for failures and sends the text to Growl for Windows, which produced the toast notification.  It even customizes the icon that Growl to use depending on whether there are failures or not – a fiery (red) Mario for failures and a happy Mario for success.
It’s a somewhat complex system that does a few other things, like dissolving each subfolder in the main project into separate assemblies and batches some git commands.  I was particularly interested in implementing the Growl notification with the failed tests.
My setup:
  1. Growl for Windows installed in c:\utils\growl for windows
  2. JP’s Mario pictures (red.jpg, green.jpg) from github copied to c:\utils\growl for windows.
  3. MSpec extracted to C:\utils\Machine.Specifications-Release.
  4. runspecs.bat (content below) added to the tests project in my solution and set to always be copied to the output folder.
  5. A post build command on the tests project:
    $(TargetDir)runspecs.bat $(TargetFileName)
Now, every time you build your solution tests will run and failures, or a success message, are sent to Growl.
The batch:
@echo on
setlocal EnableDelayedExpansion
C:\utils\Machine.Specifications-Release\mspec-clr4.exe --html .\specs.html %1|find "FAIL">fail.txt
set fail=
for /f "tokens=*" %%a in (fail.txt) do set fail=!fail!\n%%a
if not "!fail!"=="" "c:\utils\growl for windows\growlnotify.exe" /t:Build /i:.\red.jpg "!fail!"
if "!fail!"=="" "c:\utils\growl for windows\growlnotify.exe" /t:Build /i:.\green.jpg "All passed"

Visual studio passes the name of the DLL with the tests in the variable %1.  The batch asks mspec-cl4.exe to create an html report of the test results into specs.html (for later examination if needed), and also picks out the lines in mspec-cl4.exe’s console output containing “FAIL”.  Those lines are piped to fail.txt.
Next, it for loops through the lines in fail.txt and builds a batch variable called fail.  Each line in fail.txt is separated by a “\n” so that Growl puts each one on a separate line.  The !fail! syntax, alone with the setlocal EnableDelayedExpansion command, causes the batch processor to update the contents of the fail variable each time through the loop.  The usual %fail% syntax won’t do this.
Finally the batch decides if there are any failures or not and sends the appropriate message to growlnotify.exe.
image
image
Now to learn VIM and be a keyboard junkie like JP!

Friday, April 27, 2012

I Can’t Say the Ford E-250 Is A Pleasure To Drive, But It Does Its Job Well

Ikea delivery will be $169?  Bah!  We can do better than that ourselves, right?  Let’s rent a van and go get the stuff ourselves.

Such was our plan one recent Sunday morning.

You can rent a cargo van at U-Haul for $19.95 plus $0.49/km.  Great, just $20!

Wait, what’s that small print?  Oh, $0.49/kilometer.  It’s about 30 km to the Ikea in Etobicoke, so 30 km x 2 (there and back) x $0.49 = $29.4.

So we’re up to $50.

Our plan was to take the whole family to Ikea, have lunch there, let our son play in the kids area and get some big pieces of furniture.  If all went according to plan, we’d all drive to the U-Haul, I’d get the van, and we’d all drive on to Ikea.

Only, we’re a little behind schedule.  How to get me to U-Haul while mummy gets the kids ready?  Take a cab.

We’re now up to $75.

One could argue that this wasn’t a direct, unavoidable cost, but it is something I had to pay for in order to get this furniture.

At the U-Haul all went very well.  This was a Sunday and it was not busy at all.  The guy at the counter said that the previous day would have seen me waiting over an hour.  Pro tip #1: don’t rent at U-Haul on Saturday.

I decided to rent a dolly to move a big piece of furniture already in the house.  That’s another $7.  (Really?  A $40,000 van for $20, a $100 dolly for $7?  I think I’ll start a business renting just dollies.)

The U-Haul guy offered me some optional insurance on the van for about $17.  I had no idea if my car insurance or if paying by Visa covers me, so I bought that.

So all totaled, U-Haul will cost $20 + $30 (mileage) + $7 (dolly) + $17 (insurance) + HST = $83.62.  Add in the cab ride and our total so far is $108.62.

And I have to replace the gas I used before I drop off the van.  Yay.

Off to Ikea in a bill board on wheels on a windy day.  This isn’t a just a big minivan.  This is a Ford F-250 pickup-based, almost full lane-wide, 7 foot tall, 18 foot long monster.  Basic everything inside.  Geared and built for 1 thing – carrying a lot of heavy stuff from 1 place to another.  Totally exceeded my requirements.  I’d have been happy with a GMC Savana, or even just a minivan. But, it did have a line-in jack on the AM/FM radio.

The reason we chose the Etobicoke Ikea was the covered parking.  I hadn’t checked the dimensions on the van before entering the 9-foot limit parking garage, but it fit.  It quickly became obvious that I’d need to park far from other cars because of the tight spaces and corners.  Pro tip #2: when driving a new vehicle know it’s dimensions.

Shopping was ok, but the play area was full when we went to drop our son off, so there was much crying.  It was a little heartbreaking to have to tell him because we’d been mentioning it all day.  Ikea is really best visited with children on a weekday.

Ikea has spots near the door for loading your car, but in the covered parking you cannot back an 18 foot van into one of those spots.  Pro tip #3: stick to the uncovered parking with anything bigger than a minivan.  Or just wheel your purchases to your present, easily accessed parking spot.

Furniture loaded, we headed home.  Do not try to drive in anything but the right lane on the highway in a Ford E-250.  It really shouldn’t go above 110 km/h.  Anything more is a little hard to control.  It’s so wide that even the smallest variation can leave you too close to the next lane.  That’s how it felt, anyway.

By the time it was time to take the van back both children were fast asleep.  This meant I’d need another cab ride home.  Add another $25.  Replacing gas cost $20.

The final total for the day was $83.62 for U-Haul + $50 for 2 cab rides + $20 for gas = $153.62.  We saved $15.38 over Ikea’s deliver cost.  On the plus side, we got the furniture on the same day.

This could be done for much less than Ikea’s delivery cost.  Eliminate the need for the taxi, research insurance coverage, won’t need the dolly next time.  Renting a smaller vehicle from a car rental place would probably help, too. Enterprise rents a GMC Savana/Express for $50, which includes 200 km. They’d probably pick you up, too.

By the way, I didn’t even need the dolly.  The thing I wanted to move was too big for it, and it came apart just like Ikea furniture.  Live and learn!

Thursday, April 26, 2012

A Wizard Should Know Better

http://www.youtube.com/watch?v=v7NzBTRzCkg

I recently quit at CIBC and started working at Evault.  This means that my wife and I lost our immunity to account fees, kind of like when Superman transformed into a normal human.  We already had a couple of President’s Choice Financial accounts so I decided to work towards closing the CIBC ones and use only the PCF accounts.  It’s been a lot more complicated than I thought.  And the reason should embarrass any developer:  our accounts have dependencies.

In programming, one aims to create a system where no one part knows anything about how other parts work.  This is so that you can change one part without other parts caring.  Changes are limited to individual parts and don’t ripple through the system.  Thus you create a system with few, if any, dependencies on parts working a certain way.

You know how it goes with banking, though.. Sure, employer, direct deposit my paycheque. Sure, insurance company, direct debit my premiums. Sure, bank, direct debit my mortgage. Convenience now, pain later as the dependencies pile up.

Some of these are probably unavoidable, and worth the hassle, like the mortgage payment, the paycheque and withdrawals for investing.  But that’s about it.  We really should be paying everything else as a bill monthly.  Companies don’t care where the money comes from, just that account 12345 is paid in full.

The dependencies can get created recursively on you, too.  Your employer passes on the account info to your benefits and group RRSP provider(s), so you have to update those.  Hopefully these are provided by the same company, and can be changed online.  Otherwise you have to call someone, and possibly send in a void cheque.

This money stuff is all virtual.  There is no technical reason for any of this to involve talking to humans on the phone, in person, or sending snail mail.  The reason that these settings typically aren’t available online is that the systems that process this stuff within and between companies is very complex.  This is because it’s been built up over 30+ years.  Electronic payment systems predate the web by a large margin.

Our transition from CIBC to PCF is so complex that I created a Trello (task management) board.  As I write this we’re at 10 tasks done, 7 pending.  Until we complete the process we have to auto-transfer money from CIBC to PCF so that there’s money for the insurance, mortgage, etc..  Programmers might call it a bridge.

The thing that makes this transition process possible is PCF’s ability to link accounts at other banks to PCF accounts, allowing you to transfer to and from PCF accounts.  I’m pretty sure this is available at other discount banks, like ING.  Why not at the main banks?  Not in their interest, plus it’s technically complex (though not impossible.)  This would be much, much harder if the switch were from CIBC to, say RBC.  There’s no way to pay your CIBC line of credit from an RBC account online.  You’d be forced to transfer your line of credit to RBC, or visit a CIBC branch once a month with an RBC cheque.

So, do yourself a favour and limit the dependencies on your big-5-banks accounts to paycheques, strict-deadline payments like mortgages, and accounts at other banks between which you transfer money, like investment accounts.  And transfer to a low cost bank like PCF.

Keep your accounts agile.

The Truth Come Out

A few days ago:

Me:  “Should we have some of [3 year old] Ethan’s Easter chocolate?

Wife: with apparent shock, “Oh, no, that’s his chocolate.  If we want some we should just go to Mac’s.”

Me: “Ok, I’ll just have some fruit.”

Tonight:

Me: digging through the cupboard to find an empty Hershey’s Snapsy chocolate bunny box: “Mummy, what happened to Snapsy?”

Wife: sheepish grin.

Me: “His chocolate, eh?  At least he still has this other chocolate bunny.”

Tuesday, February 14, 2012

Unit Testing HTML Parsing, While Keeping AppHarbor and RefactorPro Happy

 

Short Version

“Unit” tests were starting development web server, reading web page responses using HttpWebRequests, loading them into HtmlAgilityPack HtmlDocuments and parsing them.  AppHarbor (it’s American, so no u after o) wouldn’t start the dev web server and RefactorPro parsed a very large test html page because it was part of a VS project, which took up gobs of memory.  The solution was to turn the html pages into txt files, store them as project resources and use HtmlDocument.LoadHtml to keep everything self contained.

Long Version

Yes, my unit tests were actually starting a web server and reading test versions of pages from it.  This breaks the general tenant of unit testing that they shouldn’t go “out of memory”, meaning don’t read from disk, database, network etc.  Everything should be contained within code.

So, it should have been no surprise that AppHarbor wouldn’t start a copy of the development web server for my unit tests to run against.  I knew the time had come to somehow bypass the network and read the HTML files from disk.  Use of the local dev server would be limited to working offline on the GO train.

I was also facing an issue with DevExpress’s RefactorPro.  It likes to parse every HTML file in your Visual Studio projects, just like it parses your code.  Unfortunately, one of the test pages is a list of all 11,000 products at the LCBO, and the LCBO website’s HTML is needlessly complex.  When the HTML page was included in the project it sent Visual Studio’s memory use through the roof.  I like RefactorPro/CodeRush too much to keep it unloaded when working in my LCBO Drink Locator code to disable it, so I kept the HTML page excluded from the project.  It was still on disk, and the dev web server would serve it up when requested anyway.

My first approach to the AppHarbor issue was to attempt loading the existing HTML file from disk.  My assumption was that if my unit test is in some bin\debug or bin\release folder then my HTML file is in ..\..\..\AnotherProject\doc.html.  This is true on my PC, but on AppHarbor’s build server of unknown technology configured with unknown settings, subject to change, it was not so.

The next thing I tried was to add the HTML doc as a project resource to one of the unit tests, and to load it into an HtmlAgilityPack HtmlDocument.  Thank you, StackOverflow for suggesting the approach.  Adding the HTML doc as a resource meant it was part of a project again, sending memory use sky high.  Being a resource, I couldn’t just exclude it and still have it be read from disk.  I could now load the doc from “memory” i.e. not from disk or network, but suffered long waits as RefactorPro parsed the LCBO’s crazy HTML.  (How many nested tables does a page need?)

I noticed HtmlDocument has a method called LoadHtml that accepts a plain string, which gave me an aha moment.  There was no need to make the project resources actual HTML docs; they could exist as txt files.  This meant RefactorPro would ignore them, and I could still load them from memory.  A rename and re-add as resource fixed the issue.

All my unit tests now pass on my PC and when AppHarbor runs them.

image

 

image

Not sure why AppHarbor only sees 51 tests, and not 61, but ok.

FYI, the app is hosted at http://lcbodrinklocator.apphb.com/.  It’s a work in progress, but it’s ability to destroy planets find drinks is fully functional.

image

Thursday, January 19, 2012

Not All RRSP Contributions Are Equal

Ah, January, when thoughts turn to taxes.  I still do my own because my situation is pretty simple.  My yearly routine is to put on Ace Ventura Pet Detective and fill out forms for me and my wife.  Since switching away from paper forms a few years ago to the fabulous and free StudioTax I’ve been able to watch more of the movie.  StudioTax also has a special place in my heart because it’s written in .NET.  I’m guessing the name comes from the development tool .NET folks use, Visual Studio.

This post isn’t about StudioTax, though.  It’s about something I’m sure I’ve understood from newspapers and magazines turning out to be wrong: that your entire RRSP contribution results in a rebate equal to your highest tax rate.  This is the reason tax planners sometimes recommend not contributing to an RRSP until you are in a high tax bracket, like the last 2 federal ones.  You don’t want to waste getting about 40% back by contributing when you’ll only get about 32% back.  The advice is to set aside the money until you reach one of these brackets, just not in an RRSP.  These days that place would be a TFSA account.

It’s not so simple, though, as waiting until your total income moves you to a higher tax bracket and then plowing all of your savings into an RRSP account that year.

The Math

Disclaimer: I am not a tax planner, accountant or financial consultant. There are lots of other considerations than those below to make when deciding what’s right for your situation.  I’m just exploring something I came to realize recently, which applies to my situation.

The Canadian income tax system is what’s called progressive.  Not progressive in the “this is the better way” sense, but in the “progression from one level to another” sense.  Your entire income isn’t taxed at the same rate.  The first $x is taxed at a certain level, the next $y is taxed at a higher level, the next $z at an even higher level.  The feds have their own set of x, y, z values and rates, as does each province.  Except Alberta where there is no provincial income tax.

I’ll use small, hypothetical amounts for this discussion, and assume there are no automatic tax credits, as there are in the real tax system.

Let’s say the brackets and rates are:

Income Rate
First $50 15%
Next $50 25%

You make $60 a year.  That means you owe:

Income Tax Calculation Amount
On the first $50 $50 x 0.15 $7.50
On the next $10 $10 x 0.25 $2.50
  Total $10.00

Your employer would have taken this from your pay cheque, so you’ve already paid.  If you don’t do anything more to do with taxes you owe nothing and you’ll get nothing back.

Every dollar you contribute to an RRSP (or pension plan for that matter) lowers your taxable income by 1 dollar.  Let’s do the same calculation but with a contribution of $4.

Total Income $60
RRSP Contribution $4
Taxable income $60 – $4 = $56

Plug $56 into the tax calculation table and you get:

Income Tax Calculation Amount
On the first $50 $50 x 0.15 $7.50
On the next $6 $6 x 0.25 $1.50
  Total $9.00

You’ve paid $10 through your pay cheque, you owe $9, so you get a rebate of $1.  This is equal to your contribution times the higher rate, or $4 x 0.25 = $1.

However, if your contribution lowers your income into the next bracket down, the entire contribution is not worth 25%.  Only the portion that lowers your income to the edge of the higher bracket is worth the higher bracket’s rate.  The remaining portion’s rebate rate is the rate of the lower bracket.

To demonstrate, lets say you contribute $15 of your $60 income.

Total Income $60
RRSP Contribution $15
Taxable income $60 – $15 = $45

Now you owe:

Income Tax Calculation Amount
On the first $45 $45 x 0.15 $6.75
  Total $6.75

You’ve paid $10, you owe $6.75, so you’ll get a rebate of $3.25.  Note that this is not equal to your contribution of $15 times the higher rate, or $15 x 0.25 = $3.75.  This is because it’s a combination of the potion that brought your income down to $50 at the high rate, plus the remaining portion at the low rate.  That is:

Contribution Rebate Calculation Amount
Portion to get to $50 $10 x 0.25 $2.50
Remaining portion $5 x 0.15 $0.75
  Total $3.25

Conclusion

If you’ve been waiting to make contributions until you’re in a higher bracket, and you’ve finally reached that bracket, it’s not really worth contributing more than is enough to bring your income down into the next bracket.  In the example above, it’s not worth contributing more than $10 of the $15 to bring your income down to the lower rate.  Any more contributions will only earn a rebate of 15%.  You’re better to hold on to any other savings to use in future years in hopes that your income rises faster than inflation.

Friday, January 6, 2012

Web Client Software Factory vs. Code Metrics

 

I’ve been building a web application with the Microsoft Web Client Software Factory (WCSF), and it has an interesting default option.  The option is to put interface definitions in an assembly separate from the implementation when creating a new module.  This will generate 2 projects for each module, which means at least 2 namespaces, if you don’t change anything.  This post will investigate whether the code metrics generated by this approach, specifically abstractness and instability as defined by NDepend, are worth the increased maintenance compile time.

The option can be seen here when creating a foundational module in WCSF:

image

WCSF also presents this option when creating a business module, although it still places the interface for the module controller in the “concrete” project, not the interface project.

The effect is that you’ll end up with 2 new projects, as seen in the picture above; Blah, and Blah.Interface.  The thinking is that the projects that use the services of the module need reference only the interface project.  Dependency injection will take care of locating the actual implementations.  A rather high-minded architectural choice, especially considering that for foundational modules WCSF doesn’t even add a reference to the interface project to the web project.

Let’s say you follow the intention, though, and add some interfaces to Blah.Interface, some services that implement them to the Blah project, and some views in the web app that use the interfaces.  WCSF’s behaviour aside, what’s of real interest to me is how NDepend scores these 2 projects on the abstract/instability graph:

AbstractnessVSInstability5

Blah is right near the WebClient5 assembly.  It’s perfectly instable, meaning no types depends on its types directly, and perfectly concrete, or non-abstract, because it has no abstract types.  It just implements abstract types.

Blah.Interface is perfectly abstract because it has only abstract types, and is very “stable” because while lots of types depend on its type, its types (interfaces) do not depend on anything else.  (NDepend claims Blah.Interface has 1 external type dependency, but I don’t know what.  If I eliminated this dependency then Blah.Interface would be perfectly stable.)

Now, compare the graph of the same project refactored to merge Blah and Blah.Interface:

AbstractnessVSInstability5NoInterface

Blah’s abstractness has increased and it’s “stability” has decreased.  These in themselves don’t mean much, but their relative values are still well within the area closest to the ideal dotted line. 

Given that NDepend suggests that this approach won’t result in pain or uselessness in this simple case, I conclude that the 2-project approach is not worth the extra maintenance.  This approach should be used only when it solves an actual problem, not by default for every module.