Thursday, October 28, 2004
The Code Project - Advanced Unit Testing, Part I - Overview - C# Programming
Very useful article - explores points where unit testing doesn't work well enough (atleast the normal set of tools available).
The Code Project - Advanced Unit Testing, Part I - Overview - C# Programming
The Code Project - Advanced Unit Testing, Part I - Overview - C# Programming
Very useful article - explores points where unit testing doesn't work well enough (atleast the normal set of tools available).
The Code Project - Advanced Unit Testing, Part I - Overview - C# Programming
Wednesday, October 27, 2004
Email message attachments in Perl
Email message attachments in Perl
Additional note: If you're using a MS Exchange server like me, most likely, you will not be able to send out email outside your organization. To work around this, you need to use the sign in to your SMTP server using the auth method in Net::SMTP. Give your domain username (just the username) and the password in the call to auth.
I noticed that if I included the full email id in the call to auth, the call did not fail but only the emails within the org. domain went through. I haven't really dug into this, cos I got it working with the username soon after.
Nice logs in .NET
Here's something interesting (and hopefully useful).
I've always been a fan of Log4Net (http://logging.apache.org/log4net). However, on this occasion, I had to use something that was custom built (using open source doesn't go well with certain customers). So decided to look into System.Diagnostics. The overall idea seems to be pretty simple - configure a set of trace listeners, send your trace requests to a static Trace class. The Trace class will forward the calls to each of the listeners in sequence. There's also a mechanism for multi-level logging - from nothing on to most verbose (None, Errors, Warnings, Information and Verbose). This is somewhat like the levels in log4net, but surprisingly, the Trace interface expects you to check for the switch each time you want to make a call. For example
Traceswitch ts = new Traceswitch("myswitch");
.
.
.
Trace.WriteLineIf(ts.TraceInfo, "this message will be logged if ts.level <= TraceLevel.TraceInfo);
Frankly, its too much work for me. Also, it is inefficient as the parameters will be built to a temporary object even if the trace level results in a no-op.
It sounds pretty basic - and believe me, it is. It just logs the string that it's passed. Also, there's no way to have different listeners that can each log at a different level - something like I want my file log to be at verbose level but want an event log listener that sends errors to the event log.
So, here's something that I whipped up that gets over (some of) these limitations.
My requirements were
1. Include a timestamp
2. Include caller information
3. Include an easier API for app programmers (me)
For the first, the easiest thing to do is to subclass TextWriterTraceListener and override the Write and the WriteLine methods.
The second and third require a wee bit more thought. One solution is to replace Trace class with another class that provides a more convenient interface. I called mine TraceExt with the following methods
WriteInformation
WriteError
WriteWarning
WriteVerbose
Each method has two overloaded versions - one that takes a plain string and another that takes a format string and object array as in string.Format.
Another point worth mentioning is that the TraceExt is not a static class. Rather it's expected that the class that uses TraceExt will keep a static member.
The TraceExt ctor takes the name of the trace switch to use. It instantiates the trace switch and then on, the calls to the WriteXXX are forwarded to Trace.WriteLine if the switch has the necessary level. A sample use of the TraceExt follows:
public class MainClass {
private static TraceExt log = new TraceExt("myswitch");
public static int Main(string args[]) {
Trace.listeners.add(new TextWriterTraceListener("c:\some.log");
log.WriteEntry();
log.WriteInformation("This is some string");
log.WriteExit();
}
}
Each of the WriteXXXX methods are implemented as follows:
public void Information(string format, params object[] args)
{
if (ts.TraceInfo)
{
WriteLine(format, args);
}
}
The WriteLine method is used to include other information in the logs like the caller, the method name etc. A little bit of reflection is used to get such information.
StackTrace trace = new StackTrace();
StackFrame frame = trace.GetFrame(0);
string callingMethod = frame.GetMethod().Name;
string callingClass = frame.GetMethod().DeclaringType.Name;
string callingNS = frame.GetMethod().DeclaringType.Namespace;
Sadly, just found out that I can't upload the solution file zip. If you're interested, comment on the article and leave your email id.
Email message attachments in Perl
Email message attachments in Perl
Additional note: If you're using a MS Exchange server like me, most likely, you will not be able to send out email outside your organization. To work around this, you need to use the sign in to your SMTP server using the auth method in Net::SMTP. Give your domain username (just the username) and the password in the call to auth.
I noticed that if I included the full email id in the call to auth, the call did not fail but only the emails within the org. domain went through. I haven't really dug into this, cos I got it working with the username soon after.
Nice logs in .NET
Here's something interesting (and hopefully useful).
I've always been a fan of Log4Net (http://logging.apache.org/log4net). However, on this occasion, I had to use something that was custom built (using open source doesn't go well with certain customers). So decided to look into System.Diagnostics. The overall idea seems to be pretty simple - configure a set of trace listeners, send your trace requests to a static Trace class. The Trace class will forward the calls to each of the listeners in sequence. There's also a mechanism for multi-level logging - from nothing on to most verbose (None, Errors, Warnings, Information and Verbose). This is somewhat like the levels in log4net, but surprisingly, the Trace interface expects you to check for the switch each time you want to make a call. For example
Traceswitch ts = new Traceswitch("myswitch");
.
.
.
Trace.WriteLineIf(ts.TraceInfo, "this message will be logged if ts.level Frankly, its too much work for me. Also, it is inefficient as the parameters will be built to a temporary object even if the trace level results in a no-op.
It sounds pretty basic - and believe me, it is. It just logs the string that it's passed. Also, there's no way to have different listeners that can each log at a different level - something like I want my file log to be at verbose level but want an event log listener that sends errors to the event log.
So, here's something that I whipped up that gets over (some of) these limitations.
My requirements were
1. Include a timestamp
2. Include caller information
3. Include an easier API for app programmers (me)
For the first, the easiest thing to do is to subclass TextWriterTraceListener and override the Write and the WriteLine methods.
The second and third require a wee bit more thought. One solution is to replace Trace class with another class that provides a more convenient interface. I called mine TraceExt with the following methods
WriteInformation
WriteError
WriteWarning
WriteVerbose
Each method has two overloaded versions - one that takes a plain string and another that takes a format string and object array as in string.Format.
Another point worth mentioning is that the TraceExt is not a static class. Rather it's expected that the class that uses TraceExt will keep a static member.
The TraceExt ctor takes the name of the trace switch to use. It instantiates the trace switch and then on, the calls to the WriteXXX are forwarded to Trace.WriteLine if the switch has the necessary level. A sample use of the TraceExt follows:
public class MainClass {
private static TraceExt log = new TraceExt("myswitch");
public static int Main(string args[]) {
Trace.listeners.add(new TextWriterTraceListener("c:\some.log");
log.WriteEntry();
log.WriteInformation("This is some string");
log.WriteExit();
}
}
Each of the WriteXXXX methods are implemented as follows:
public void Information(string format, params object[] args)
{
if (ts.TraceInfo)
{
WriteLine(format, args);
}
}
The WriteLine method is used to include other information in the logs like the caller, the method name etc. A little bit of reflection is used to get such information.
StackTrace trace = new StackTrace();
StackFrame frame = trace.GetFrame(0);
string callingMethod = frame.GetMethod().Name;
string callingClass = frame.GetMethod().DeclaringType.Name;
string callingNS = frame.GetMethod().DeclaringType.Namespace;
Sadly, just found out that I can't upload the solution file zip. If you're interested, comment on the article and leave your email id.
Wednesday, September 01, 2004
An OO Text filter library in Perl
And then I got thinking and realized that 90% of the time I am trying to match text delimited by some patterns and trying to do something with the text in between - for instance, add log statements at start and end of function calls in a VB.NET source, clean up objects at end of function etc etc.
public function f
----
----
----
.
.
----
end function
public function g
----
----
----
.
.
----
end function
Also, being able to string two (or more) filters one behind the
other was another must have feature. i.e., filtered output of the first becomes input for the second.
And being able to negate a filter would be of added use - I guess it'll just ease up stuff syntactically.
So I've been spending quite some time in the past two days and have finally the app code looks simple as I'd wanted...
#! /bin/perl
use strict;
use TextRegion::StartFilter;
use TextRegion::StartEndFilter;
use TextRegion::AndFilter;
my ($filter1, $filter2, $andfilter);
sub onMatchBegin; #app code callback
sub onMatchEnd; #app code callback
$| = 1;
$filter1 = new TextRegion::StartEndFilter('^\w+:\d+>\s*sysbuf', '^\**DONE\**ERRORBUF');
$filter2 = new TextRegion::StartFilter('^SWER');
$andfilter = new TextRegion::AndFilter($filter1, $filter2);
$filter2->onBeginEvent(\&onMatchBegin);
$filter2->onRegionEndEvent(\&onMatchEnd);
$andfilter->start;
while(<>) {
$andfilter->apply($_);
}
$andfilter->end;
Am I on top of the world today!!! :D :D. Actually, the fun part of
programming is that spark of an idea that you can build and give a tangible shape - always beats me how people can't not like programming.
An OO Text filter library in Perl
And then I got thinking and realized that 90% of the time I am trying to match text delimited by some patterns and trying to do something with the text in between - for instance, add log statements at start and end of function calls in a VB.NET source, clean up objects at end of function etc etc.
public function f
----
----
----
.
.
----
end function
public function g
----
----
----
.
.
----
end function
Also, being able to string two (or more) filters one behind the
other was another must have feature. i.e., filtered output of the first becomes input for the second.
And being able to negate a filter would be of added use - I guess it'll just ease up stuff syntactically.
So I've been spending quite some time in the past two days and have finally the app code looks simple as I'd wanted...
#! /bin/perl
use strict;
use TextRegion::StartFilter;
use TextRegion::StartEndFilter;
use TextRegion::AndFilter;
my ($filter1, $filter2, $andfilter);
sub onMatchBegin; #app code callback
sub onMatchEnd; #app code callback
$| = 1;
$filter1 = new TextRegion::StartEndFilter('^\w+:\d+>\s*sysbuf', '^\**DONE\**ERRORBUF');
$filter2 = new TextRegion::StartFilter('^SWER');
$andfilter = new TextRegion::AndFilter($filter1, $filter2);
$filter2->onBeginEvent(\&onMatchBegin);
$filter2->onRegionEndEvent(\&onMatchEnd);
$andfilter->start;
while() {
$andfilter->apply($_);
}
$andfilter->end;
Am I on top of the world today!!! :D :D. Actually, the fun part of
programming is that spark of an idea that you can build and give a tangible shape - always beats me how people can't not like programming.
Saturday, August 28, 2004
Perl - you'll either love it or you'll hate it, but you won't ignore it if you want to get things done!
aid my fiance' in doing some log analysis. And I'm no Perl guru - my biggest Perl program till date wouldn't have been more than a 100 lines.
Here's my raves and rants on it
Raves
- Most powerful reg ex capabilities with a full programming language
to back it up! - Large and powerful standard library.
- Platform independent
Have windoze at work, usually am on a cygwin console and have
linux/windows dual boot at home. Perl doesn't complain!
Rants
- Syntax - I've never got used to the ultra concise Perl vars. But
then, I dont use it regularly enough. Still, the syntax just isnt
readable. - Syntax isn't orthogonal - guess what I'm trying to say is that there
isn't one and only one way to achieve something. While this is totally
against the Perl mantra of "There's more than one way to do it", in
spite of using it on and off, I've never been able to embrace- References
- Subs
- OO Perl
- Writing perl mods
I've used all of them at sometime or the other but the next time I
pick up Perl to do some nifty little script, I find myself going
through perlsub, perlref, perlreftut and perltoot - not nice!
I guess at sometime I did come across Python - which is supposed to
address all the shortcomings of Perl while retaining the pluses. But then once I got everything set up, saw that its indentation sensitive!! Now does that remind me of something....called FORTRAN ??
Anyway, it put me off so much that I never took a look at it again - probably I should, and be more generous while at it!
Meanwhile, I'll use Perl the next time I need to write a nifty little
script to do some text analysis.
Interested? - I'll recommend Robert's perl tutorial.
Programmer: n. Person who spends 10 hours automating something that
takes an hour manually just so that
- He can see his program complete the work in 1 hour.
- He can tell his poor kith and kin what a great guy he is.
Perl - you'll either love it or you'll hate it, but you won't ignore it if you want to get things done!
Here's my raves and rants on it
Raves
- Most powerful reg ex capabilities with a full programming language to back it up!
- Large and powerful standard library.
- Platform independent. Have windoze at work, usually am on a cygwin console and have linux/windows dual boot at home. Perl doesn't complain!
Rants
- Syntax - I've never got used to the ultra concise Perl vars. But then, I dont use it regularly enough. Still, the syntax just isnt readable.
- Syntax isn't orthogonal - guess what I'm trying to say is that there isn't one and only one way to achieve something. While this is totally
against the Perl mantra of "There's more than one way to do it", in spite of using it on and off, I've never been able to embrace- References
- Subs
- OO Perl
- Writing perl mods
I've used all of them at sometime or the other but the next time I pick up Perl to do some nifty little script, I find myself going through perlsub, perlref, perlreftut and perltoot - not nice!
I guess at sometime I did come across Python - which is supposed to address all the shortcomings of Perl while retaining the pluses. But then once I got everything set up, saw that its indentation sensitive!! Now does that remind me of something....called FORTRAN ??
Anyway, it put me off so much that I never took a look at it again - probably I should, and be more generous while at it!
Meanwhile, I'll use Perl the next time I need to write a nifty little script to do some text analysis.
Interested? - I'll recommend Robert's perl tutorial.
Programmer: n. Person who spends 10 hours automating something that takes an hour manually just so that
- He can see his program complete the work in 1 hour.
- He can tell his poor kith and kin what a great guy he is.
Friday, August 27, 2004
A new day, some tweaks and a little bit of *nix
Have posted a query to google feedback - will let you know if something comes of it.
Meanwhile have started looking at NUnitForms - have to try out some code to see if it's as nice as nunit. If any of you have tried it out, please do post your suggestions and feedback on the tool.
On an aside, with console driven tools (nant, nunit etc) gaining popularity, I find myself running the cmd.exe a lot more. I've been a long time (> 2 years) fan of cygwin for running bash and other *nix tools on windows and it certainly helps that I can run all .net command line tools from there. However, it does have its wrinkles - it recognizes only unix style paths and this sometimes gets me into trouble. So for that I have to resort to cmd.exe - where I've always missed tab completion for files and folders. Found a couple of tweaks that get you *nix behavior on windows:
- Command prompt in the context menu in Explorer (win 2000)
- Open explorer
- Tools->Folder Options ->File Types
- Type n in the list boxand navigate to 'Folder' item
- Click Advanced in the bottom frame. An Edit File Type window pops up.
- Click New - and in the Action Box, enter Command Prompt. In the Application Box, enter "cmd.exe".
- Close all windows and restart explorer. You should have a new context menu for folder items called "Command Prompt"
- Tab completion as in *nix.
- Open the registry with Regedit.
- Navigate to the key
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Command Processor - Set the values for CompletionChar and PathCompletionChar to 0x09
[You can download power toys for various windows versions for this behavior, but I like to do it without yet another download]
A new day, some tweaks and a little bit of *nix
Have posted a query to google feedback - will let you know if something comes of it.
Meanwhile have started looking at NUnitForms - have to try out some code to see if it's as nice as nunit. If any of you have tried it out, please do post your suggestions and feedback on the tool.
On an aside, with console driven tools (nant, nunit etc) gaining popularity, I find myself running the cmd.exe a lot more. I've been a long time (> 2 years) fan of cygwin for running bash and other *nix tools on windows and it certainly helps that I can run all .net command line tools from there. However, it does have its wrinkles - it recognizes only unix style paths and this sometimes gets me into trouble. So for that I have to resort to cmd.exe - where I've always missed tab completion for files and folders. Found a couple of tweaks that get you *nix behavior on windows:
- Command prompt in the context menu in Explorer (win 2000)
- Open explorer
- Tools->Folder Options ->File Types
- Type n in the list boxand navigate to 'Folder' item
- Click Advanced in the bottom frame. An Edit File Type window pops up.
- Click New - and in the Action Box, enter Command Prompt. In the Application Box, enter "cmd.exe".
- Close all windows and restart explorer. You should have a new context menu for folder items called "Command Prompt"
- Tab completion as in *nix.
- Open the registry with Regedit.
- Navigate to the key
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Command Processor - Set the values for CompletionChar and PathCompletionChar to 0x09
[You can download power toys for various windows versions for this behavior, but I like to do it without yet another download]
Thursday, August 26, 2004
I'm back...
These days am looking for some generous person to invite me to Gmail.
Haven't really done much on the programming front - other than digging around to find out if I can launch an executable on the client from a web page without the warning pop ups.
Read KB 232077 on MSDN for a solution using cab files.
I'm back...
These days am looking for some generous person to invite me to Gmail.
Haven't really done much on the programming front - other than digging around to find out if I can launch an executable on the client from a web page without the warning pop ups.
Read KB 232077 on MSDN for a solution using cab files.