Sunday, June 29, 2014

notepad++ regex replace group

Problem
I am updating legacy code where assignments can be done in two ways:
Way 1 - set field to value;
Way 2 - field = value;

I'm used to Way 2, so i want to mass update Way 1 to Way 2 in order to make it more readable.

Solution
Using Notepad++ using the Replace tool with regex.

1. In Search Mode choose Regular expression. Make sure "Wrap around" is checked.

2. Capture groups are done by using parentheses. So in Find what put set (.+) to (.+);

3. Then you can use the value from the capture group by using \#. So in Replace with put \1 = \2;

Reference
http://stackoverflow.com/questions/3218063/notepad-replace-problem

Saturday, June 14, 2014

Adapter, decorator, and facade patterns

Decorator: wraps the interface of a class to add functionality. This can be done by delegating or subclassing.

Adapter: maps one interface to an expected interface. This is so client code doesn't need to be changed when an interface changes. This can be done by subclassing the expected interface and wrap-and-map the unexpected interface.

Facade: take a complex interface, which may be composed of several classes, and simplify the interface with a Facade class that hides lots of the details.

Friday, June 13, 2014

Trigger register error #2 - SY_INVALID_SCRIPT

Problem
I want to contain all code for a certain module in one form. When i go to register a focus trigger against 'Save Button' on a form, and set the processing script to a script on my form, it is giving me registration error #2, which means the processing script is invalid.

Solution
Apparently you cannot specify a script that is contained in a form for a focus trigger. It has to be a global script.

Comments
No wonder this legacy code has 100's of global scripts, it's forced. This had lead to an epic mess because these scripts can't be logically organized.

Thursday, June 12, 2014

Trigger won't register in Dynamics GP

Problem
In Startup i'm checking if multicurrency is registered:
if 'Module Registered'[MCUR] of globals then
{register triggers}
end if;

but it is never registering the triggers, even though MC is registered!

Solution
Apparently the Module Registered global field doesn't get populated before the login takes place. This means the conditional above is never going to succeed, thus resulting in the trigger registration never getting hit.

Instead of putting the check here, put it in the trigger procedures themselves. 

Wednesday, June 11, 2014

Warning dialog won't wrap text in Dynamics GP

Problem
The warning dialog text doesn't wrap

warning "The card must have the option Accepted from Customers checked";


Solution
Put a period at the end!

warning "The card must have the option Accepted from Customers checked."; <--- period


Friday, June 6, 2014

Command Pattern

Requester -> Command invoker -> Receiver

I have this pattern implemented right now. We have a product that is complied against a specific dll version, then it must be deployed with that. Every time the interface changes in the dll you have to remove the reference, unregister the DLL from COM, and then register the new one. It makes development and deployment unnecessarily difficult.

Instead of putting up with that crap for long we implemented the Command Pattern without knowing it was called that!

Product -> command invoker dll -> receiver dll that does the work

This allows us to develop much painlessly because changes to the interface are not visible to the product since it's going through the command invoker.

The command invoker uses assembly reflection in .net. The requester needs to pass in the method name + params. 

Right now we also have a job scheduler, but it's not decoupled from the job executing objects. Now that I learned about this pattern I can solve this problem :)

Sunday, June 1, 2014

Lessons learned from reading Martin Fowler's "Refactoring" book

 A few rules of refactoring
 1. Refactoring should not change the output of a program. It should only change the structure of the code.

2. The code you're about to refactor should have tests in place before starting. Tests should then be ran after each small refactoring step.

3. Because of schedule constraints it's often best to "nibble around the edges" instead of diving into a big refactoring. 

4. Before starting a coding task (feature or fixing a bug) refactor the area you're going to be working in, then make the change.

Knowledge found here that was found in other places
1. Duplication is bad

2. Write code with clear intentions. 

3. Comments should explain why, not how. The code explains how.

4. I started reading another book at the same time as this one called Head First Design Patterns. I saw several patterns achieved as the result of refactoring. This means in existing systems design patterns should be strived towards. 

Refactoring catalog
Too many to copy or comment on. http://refactoring.com/catalog/
There was an error in this gadget