Monday, October 30, 2006

Do you eat your own dog food or someone else's?

Adam Barr does it again with another great post, this time about the tendency to use your company's own tools instead of your competitor's, even in everyday life.

The sum up? "That's an honestly-earned win for IE. And that's the kind of win we should be targeting, not a forced switch just because." - great post.

Reading/Writing Data from a Text File: VFP and DotNet

(note: the title of this post is based on what I started to write about which is comparing functions between VFP and DotNet but then went off onto a tangent about code readability)

While I do work in Visual Studio and DotNet a fair bit, my main development environment is Visual FoxPro. One of the things that I always remember from past Devcons was when Microsoft was really trying hard to rally the FoxPro-faithful to use DotNet and ADO.Net, and even at the first DevTeach when there were a fair number of FoxPro developers, (before it turned into a Fox-less event), was the justification for the way most things were objects in DotNet and how that made it better than the single function approach in VFP.

It always struck me as a "this is the right way to do it - so switch to using this approach, regardless of ease of use" type of argument. I know it wasn't intended that way - but that's the impression I always got. And I got it again recently.

Rhonda Tipton explains here how to use the StreamReader class in .Net to read in a simple text file. Just in case there may have been an easier way, a similar approach was noted here and here.

Since I've been doing work on the Code Analyst, I'm always trying to find ways of reducing the number of lines of code in my programs and it just strikes me as crazy that the latest version of a tool actually makes your code longer than it needs to be.

For example, to write to a file using C#, the code displayed was:

StreamWriter sw = new StreamWriter("
C:/NewCompanySecret.txt");
string line = "Don't tell anyone!!!";
sw.WriteLine(line);
sw.Close();

(and this is without the various Implement statements)

compared with:

STRTOFILE("Don't tell anyone!!!","C:\NewCompanySecret.txt")

in Visual FoxPro.

Reading code:
StreamReader sr = new StreamReader("
C:/CompanySecret.txt");
string line = sr.ReadLine();
while (line != null)
{
System.Console.WriteLine(line);
line = sr.ReadLine();
}

sr.Close();


Compared with:

lc = FILETOSTR("C:\companysecret.txt")

or better yet, my favorite:

lnLines=ALINES(la,FILETOSTR("C:\companysecret.txt"))

(which makes it easier to find specific lines and make changes)

I do like the idea of having a string and doing SUBSTRINGs in them:
line.Substring(0, 21).Trim()

But it kind of reminds me of Word automation (which I also had to do recently), where you have to deal with Selection.Range.text instead of just saying ActiveDocument.text, etc.

I'm not saying it's harder or VFP is better as the functions do the same thing but it reminds me of someone who purposely talks in a strange dialect just to make it seem like they are superior, or maybe just of the Emperor's new clothes.

There are many cases (especially in frameworks) where you have to make things more complex. For example, you create a data manager class to open up files and handle it with error handling:

myData.Open("CUSTOMERS")

as opposed to simply saying

USE CUSTOMERS

So it certainly is a learning curve thing.

But I also think it's useful to look at your tools and code based on a few basic goals (not necessarily in this order):

a) readability
b) maintainability
c) functionality

Readability can be, in my mind, very subjective. ToString() certainly seems far more readable than CStr() (VB) or STR( )(VFP). Likewise a user-defined method named GetAccess() seems more usable than p0acc().

But if you have to read 25 lines of code to understand a procedure or if you have to read 5 lines, which would you prefer?

And I also would say that maintainability also comes from a code's readability factor.

As part of the Code Analyst VFPX project, I'm really interested in finding ways of making suggestions to other developers on how to make their code more readable and more maintainable. Some of the default rules can be seen here.

So join the discussion (or take the poll) and let me know - how maintainable is your code?

Monday, October 23, 2006

Is there a good reason to mark a class public?

Scott Hanselman has a great post from a presentation at TechEd2006 on building frameworks, comparing the theory behind good framework design and the reality.

What's great is he includes slides with the points on them.

My favorite? If they extend it, they will break it.

Saturday, October 21, 2006

Friday, October 20, 2006

Rick and others at Southwest

Sigh! Another missed conference - another plea for conference blogger!

And this one will be hot too - not just with the weather - but with all the cool stuff found in Visual FoxPro 9's preview of Sedna and SP2.

Looking forward to those reports guys!

Southwest Fox Starts

Monday, October 16, 2006

I was bit by a 2.6 year old Fox(Pro)

Talk about old ghosts coming back to haunt you.

I was upgrading a customer's old Foxfire! installation from version 3.0 to 8.0. They were running Foxfire! 3.0 under FoxPro 2.6/Windows.

But they had this one report that kept on crashing under the 8.0 version that would run fine under their old version.

I tried to run Foxfire! 3.0 under a copy of Visual FoxPro and it crashed there as well.

Hmmm...what could it be? I looked at the SQL generated.

There was the problem that was causing the crash: one of the relationships was referring to a field that didn't even exist.

The field in the SQL referred to a field named PART_SEC_ID_I but the real field was called PART_SEC_I.

But why didn't it crash under the older version?

The reason? FoxPro 2.6 ignored the extra fields.

I opened up the table in FoxPro 2.6.

? part_sec_i
** returned a value
? part_sec_id_i
** returned the same value.

Sheesh...I can't believe we were actually able to build quality applications back then but then again, when our tool wouldn't even tell us we were wrong in our field names - who needed field validation?

Now the fun part - how to tell someone that even though their old application worked great, it was actually not reporting a problem it should have been.

Why You Can't Close On PocketPCs

Mike has an excellent post on why Microsoft did what they did with the Pocket PC regarding managing memory. I love posts that help explain why decisions were made in software, even if you don't agree with them. And the comments bear it out.

Check it out here: Windows Mobile Team Blog : The Emperor Has No Close

Wednesday, October 11, 2006

The death of habeas corpus

I typically stay out of political matters on this blog but this article isn't a very good sign about the state of the world.

True, Olbermann typically has a razor-sharp tongue on many points but this one is further backed up by this Wikipedia article.

Considering what Canada just went through with the Arar report, it doesn't look good for basic justice anymore.

The death of habeas corpus - Countdown with Keith Olbermann

Monday, October 09, 2006

Creating Passionate Users

This post has gotten a lot attention and for all the right reasons so I wanted to re-iterate it here.

"If you knock out exuberance, you knock out curiosity, and curiosity is the single most important attribute in a world that requires continuous learning and unlearning just to keep up."

I have to say the list of traits as to why Robots make the best employees sounds scarily familiar to me. Do you know companies or developers who fit into that category?

This is why developers have to fight burn-out.
Creating Passionate Users: Knocking the exuberance out of employees

Be careful of TreeView.Nodes.Clear

As you may have surmised from my last post, we were dealing with some performance issues in a treeview when it was repopulating nodes. This is an older tip but it's certainly something to consider if you are using TreeViews. I got the tip here and it's a good one.

When the Nodes.Clear method is called, it refreshes the treeview for each node it removes.

If your treeview is small, you won't really notice it but if you have a lot of entries on it, it's really noticeable.

Here's a quick test to try
1. Build a form with a treeview on it.
2. Add 200 nodes to it:
WITH THISFORM.TreeView
FOR lni = 1 TO 200
.Nodes.Add(,"_"+LTRIM(STR(lni)),"Item "+LTRIM(STR(lni)))
ENDFOR
ENDWITH

3. Just issue a _SCREEN.Activeform.treeview.nodes.clear() in the Command window and see how long it takes for control to come back. It can be a while. (my test showed 14 seconds - YIKES!!!)

Instead, remove each node individually:

FOR lni = 1 TO THISFORM.Treeview.nodes.Count to 1 STEP -1
THISFORM.TreeView.Nodes.Remove(lni)
ENDFOR

The result? The list goes away in under a second.

Sounds like if you have a tree view in your application, you should subclass it and create a clearNodes method to get rid of it.

The other approach?

THISFORM.treeview.visible = false
THISFORM.treeview.nodes.clear
THISFORM.treeview.visible = true

Another instant result.

Writing better code in action...

Early this year, Andy Kramek wrote about Writing better code (Part 1).

I just saw an example that I thought would be worth sharing.

This system was using a treeview with two different "purposes". One was to show a list of about 10 nodes and the other showed a list with about 200 nodes on it.

When the system ran, it just seemed super slow. The first list would appear fairly quickly but then when it switched between the two, it would reduce to a crawl, even just to show 10 nodes.

Why?

The loop looked like this:
SCAN
lnRec = RECNO()/RECCOUNT()*100
Treeview.Nodes.Add(xxx,xxx,xxx)
DOEVENTS
ShowProgress(lnRec)
ENDSCAN

DOEVENTS is useful for allowing any Windows activity to refresh - so it's useful to call it - but calling it within the SCAN means it will take a hit on performance as well as the ShowProgress for every record.

As Andy notes: "Inform your users, but don’t compromise performance to do so"

With a few minor tweaks, the code now runs incredibly fast and I was able to point the programmer in question to Andy's great post about it.

As I noted last week, these are the types of things that the development environment need to be catching to make us all better developers.

Kind of like having a Peer Review happening in real time.

Thanks Andy - once again for having great tips easily available!

Wednesday, October 04, 2006

Luis makes a FoxPro Outlook Popup!

Luis Dangel shows off a great Visual FoxPro Popup Class that looks and works similar to Outlook's pop-up menu.

Yes, you can create a shortcut menu in FoxPro but this one LOOKS like Outlook's which is great.

Looks like Luis is looking for a builder to create it - myself? I think a GenMenuX Driver is called for.

Let me see what I can do on this...

Tuesday, October 03, 2006

Kevin Ragsdale's Desktop Alerts Rock

So if you have ever wanted to have alerts pop-up like they do in Outlook, Kevin's got a great screen cast that walks through how he did this in Excel. He also had his intro one back from Sept 25 - here's the link so you know what he's referring to.

Warning: the screencast takes some time to popup but it's a very effective way of showing how this tool works, including from other applications such as within Excel.

I just added some basic toolbar Alerts to my application and now I'm totally jealous. I have to redesign it as Kevin's implementation totally rocks!

Now the question is: where's the code?

Kevin Ragsdale : Screencast: Desktop Alert Callbacks

Monday, October 02, 2006

What will you do with VFPCompression ?

Craig Boyd has posted about his Visual FoxPro VFPCompression library, a tool that lets developers programmatically zip and unzip files.

While many may immediately see the benefit of using this approach for aiding in backing up files, there's another use that may not be immediately obvious.

Zipped documents for backup are nothing new but file formats that are actually zip files with multiple documents are becoming more popular. MindJet's MindManager has used a Zipped file format since 2005 (maybe even earlier) and Office 2007 will also be using this approach.

Essentially what it means is that a Word Document (.docx extension) can be renamed to ZIP and decompressed. Inside the zip file are all of the pieces required to define the Word document. You can also use Word to open other file formats as well. Read the walkthrough to get a better understanding.

But how can you use this new approach in your FoxPro development? Well, thanks to the VFPCompression FLL, dealing with the individual zip portion becomes a lot easier so now we can think of uses in applications:

1) static lists or rarely updated files can now be stored in zip files, only being compressed or decompressed on application startup.
2) memo field usage can be reduced by storing the values in a stream that is then compressed (thus, avoiding memo field bloat)
3) application core data can be backed up on startup and shutdown, ensuring reliable backups stored elsewhere
4) updates can be packaged or sent to users and automatically unbundled
5) error logs can be compressed
6) application data can be stored in a single "file format" making it easier for applications to copy data around

Do you plan on taking advantage of this method of storing data? If so, how?

Where Development Dollars Could be Spent

Markus notes that
Error Messages Drive Me Crazy and he's right. One can simply read various posts on the issues with Visual Studio to get a feel for it. Yes, it's hard to catch every bug - and fixes come along every while that help things out and the knowledge you gain on debugging certainly helps but if you're looking for things to concentrate on, as Markus notes "Giving me better error messages would remove my main productivity hurdle..."

Great post.

Rick and others are MVP'd again!

With all respect to John's list, Microsoft also does a good job of recognizing those individuals who do a lot for FoxPro, even if some of it is on the financial side of things. Just as John's list came out, the October round of FoxPro MVPs was announced and what a great list:

Rick Schummer
Alex Feldstein
Eric Den Doop

Ted's got a good list here!

Shedding Some Light: MVP'd again!

Do your bugs lurk?

Adam Barr has a great post about debugging: Software Engineering Goal: Expose Bugs Faster in which he suggests that the critical task in improving software engineering is decreasing, not the bug count, but the lurkability of bugs.

FoxPro is terrible for lurking bugs. Think of C5 errors. If you have a missing object pointer somewhere, it will generate a C5 error. but not immediately - just later on at some point in time.

Yes, we know about some resolutions to this (Don't Return Inside With), but it's a great example of a lurker.

Which is one of the reasons why tools such as Coverage Profiler and FoxUnit exist - (read Eric Sink's great post about Code Coverage). It's also one of the reasons behind my earlier work on the Code Analyst, as part of VFPX.

I'm getting ready to get started on building further betas on this (Randy Jean had asked me about it at the beginning of last month and I have been too buried to get into it). We've already got a list of some of the more basic checks to find lurking bugs (such as looking for RETURNS inside ENDWITH) as well as more cosmetic ones.

If you haven't seen the earlier versions of it, you can see a little of it in action here.

What tips do you use to catch your lurking bugs?