Miguel cites Joel

Hey Mr. Jorge Castro, arslinux folks, and other Joel haters,

What do you Gnome and Linux fan boys think about Miguel citing the use of a Joel principle?

Our current focus is on delivering a very stable platform, so we are trying to fix the bugs that people are reporting and give developers a great experience with their existing code base. This is just a basic Joel principle: fix bugs before you write new code.

Just for the record, I am a huge Joel fan. I’ve read many of his essays and his latest books. The only points where I disagree with Joel are on the virtues of free and open source software, and the value of operating systems such as Linux and BSD. I simply think there is a place for these things in the software world.

update:Wow, my poor English. I used sites instead of cites above.

Three tools which over the past week or so I’ve come to wonder how I ever lived without them. .NET tools and Visual Studio plugins

Three tools which over the past week or so I’ve come to wonder how I ever lived without them.

GhostDoc – I like to use CTRL-SHIFT-D as the shortcut key for “Document This”. My favorite feature is that when you are documenting an inherited function (virtual or override) it pulls the documentation from the parent class. In many cases like when implementing IComparable’s CompareTo, or Equals or GetHashcode, this default documentation is an excellent starting point. Often I only have to write one more detail sentance.

NUnit – Unit testing is a requirement. Well, it is required by me. You can guess why I’m overriding Equals so much and writing docs with GhostDoc, it is to have better unit testing ability.

NDoc – Even if others aren’t consuming your code, having good documentation is highly beneficial. NDoc generates MSDN like documentation in the form of html and chm files. It can even optionally generate LaTeX documentation! This will be great when I want to sell the paper form of my documentation 🙂

Coding Conventions

update: Oops, I thought I posted this a “private” in wordpress, but I guess not. This post was really meant as a note to myself so I could refer back to it later on. It is directly ripped from the Project Ardvark specification which Joel Spolsky made public. Sorry for filling your RSS or whatever with notes to myself, I’ll try to do a better job using WordPress.

Always use the same name for the same thing. For example, the name of an INPUT in HTML should
correspond to the name of the variable it gets stored in, which should correspond to the name of the
column in the SQL database.
In C# code use Apps Hungarian, a.k.a. Aardvark Ukrainian. Having a stronger coding convention for
names helps keep code correct, but it also helps you remember variable names because theres less
variability, and it saves mental stress when you have to figure out a new variable name because so many
are predictable.
Variable names are lowerCamelCase, e.g. prefixName
Common prefixes:

  • s = a Unicode string
  • ch = a single Unicode char
  • a = ANSI modifier. as = ANSI string; ach = ANSI char.
  • utf8 = A UTF8 string
  • c = count of something. So cb = count of bytes (buffer size), cch = string length
  • ix = index the unique primary key of a database or an index in a loop or an index
    into an array
  • rg = (range) an array, usually as a prefix. For example rgs is an array of strings
  • f = Boolean flag, always true/false. Although traditional Apps Hungarian allows threestate
    flags we dont.
  • fl = File
  • fn = Function (when you have a function pointer)
  • path = Path, the full path name of a file
  • n = n-way flag or enum
  • b = byte.
  • db = database
  • dbl = floating point number
  • l = long, by which we mean, a long integer that is not a count of something
  • x, y = x or y coordinates in pixels.
  • d = difference. Commonly used in dx or dy to indicate width or height, but could also
  • be used as ddt (timespan), dix (offset in an array)
  • dt = date/time (includes both)
  • rs = recordset
  • sql = sql statement
  • tbl = database table
  • url = a complete URL.
  • urls = a string which has been URL-encoded
  • html = a string which contains HTML and is suitable to dump to the browser as-is
  • p = pointer modifier. Used for a pointer in C/C++; not needed in C# code.
  • o = object.

When you define new classes, pick a Ukrainian prefix to use for that class of 2-4
letters, and document it at the top of the class definition. So for example if you defined
a class called CSession you might decide to use sess as the prefix.
Common names or suffixes:

  • Min, Max = minimum and maximum
  • Prev, Next, Curr = previous, next, and current
  • Tmp = a temporary value
  • Src, Dest = when copying things

The name part is often omitted when there is only one local object of the type youre dealing
with or one which is most important. For example, if you write a string function that takes one
string argument, its just going to be named s. The arguments to a function that writes a string
to a file would obviously be named (fl, s).
Function names are UpperCamelCase. Use TypeFromType for conversion functions, for
example, Utf8FromS would be a function that converted Unicode to UTF-8.
Class names start with C or E. (Objects of that class should use their own prefix which you
coin.) Use E for entity classes, that is, classes which correspond to a single row from a table or
view in the database. Use C for all other classes.
SQL Tables are always UpperCamelCase and named in the singular, for example, Customer
and Person, never Customers and People.
Virtually every table contains an autonumber (identity) it is always the leftmost column, is
always the primary key, and always named ixFoo where Foo is the table name. For example if
your table is called Customer there is certain to be a PK named ixCustomer as the first column.
If any other tables have foreign keys pointing into your table, they will be named ixCustomer,
too, unless they have several, in which case, append a modifier. For example ixCustomerFirst,
ixCustomerCurrent, ixCustomerReferrer.
In SQL tables, we use the same prefixes as we use in code. The most common are dt, f, n, c, and
ix. Strings are usually just s unless html or url is more appropriate, but we sometimes use txt for large text (memo) fields. All SQL tables start with tbl, views start with view, and we hope never to use stored procedures.

Saturday Night Experiment

Time: ~7:33pm
Yes, life ain’t the party it used to be. Gone are the late nights of clubbing and replaced are the quiet country nights of sitting at home and… and… well… trying to find anything to do.

Since the wife is in graduate school and spends every free hour studying (read: this means she has little to no “free” hours), I decided, about five minutes ago, that this Saturday night would be different. It is 7:35 PM. (I guess I decided at 7:30PM) She said she would have to study until midnight. I have decided to conduct a little experiement of my own. I have 4.5 hours to design a web application, implement it, and document both the application at the process. What you are reading is the documentation of the process.

I recently took the Ruby on Rails Todo List tutorial. Ruby on Rails is definitely an awesome web application framework (I hate these buzzwords and titles too, but to steal from MTV, I’d call the name “buzz worthy”). Rails will be my tool of choice for my mission. The mission: Write a web application book reader for reading titles from Project Gutenberg.

I’m off to write the specs.
Time: 7:40pm

Time: 7:50 pm
Specs written:

Book Reader specification

OVERVIEW

Installation – not sure, because not sure what ruby on rails is capable of, handle this at another time.

Use –
The main page should give a menu allowing selection of a reading list, current reading, and past reading.
The reading list is a list of books to be read. A browse system for finding books in Gutenberg library should allow books to be added to the reading list.

Books being read and past reading should have multiple bookmarks. There can be 3 types of bookmarks. First is the primary bookmark, this is where teh user left off reading. Second is dogears, this is for points in teh book that are intersting that the user may wish to return to. Third is highlight, these are really just like dog ears, but different types of users may work, think, and feel differently about their books. Highlighs highlight text for easy finding later.

stage 2:
The next set of features probably won’t get implemented immediately, they are teh stage 2 features: Allow preferences for reading books by paragraphs per page (to speed load times), chapter views, and an RSS view. The RSS view oculd be a chapter or number of paragraphs every N days and RSS would be generated for that number of paragraphs or chapters in such increments. Reading the book now becomes as simple as subscribing to the RSS feed.

Stage 2 backend:
Try various gutenberg mirrors in parallel, allow selecting a prefered mirror. Specify a limited local book cache size.

DETAIL

Rails is an MVC, so expanding the above gives natural models for ReadingList, Library, Reading, and Books. Past and Current Reading are really just cases of Reading with a simple boolean switch indicating that the user is done with this Bok.

Properties of Books should come from Gutenberg, so use natural properties for thier publication.

Time to fill up the coffee cup, and check the bread (I’m baking bread while I do this too).

Time: 8:15pm
Coffee cold already. I’ve laid out some tables. I’ll need to parse GUTINDEX.ALL and populate the database with its results. I can do this outside the web application.

I’m getting distracted a bit right now. The first loaf of bread goes into the oven in about 15 minutes. The second loaf about 30 minutes after that. I probably shouldn’t be multi tasking while trying to program. Oh Well, at some point I’m going to clean the tub and take a shower too. I’m aiming for that to be my 10pm 1/2 time break.

The tables are going to look like this: (in psuedo schema)
GUTINDEX:
GUTINDEX_id series/autonum
releasedate,
name varchar(100),
author varchar(100),
SeriesNumber int,
basefilename varchar(30),
booknumber int
GUTINDEXProperties: –e.g. (full)Title, Subtitle, Editor, Language, Illustrator
GUTINDEXProperies_id series/autonum,
GUTINDEX_id int, –fk
Property varchar(20),
Value varchar(100)

# parse GUTINDEX.ALL to populate these tables.
User
User_id seq/auto,
UserName varchar(50),
UserEmail varchar(50),
–whateverelse
BookStatus
BookStatus_id seq/auto,
BookStatus varchar(100), — in ReadingList, CurrentReading, Past Read
User_Books
User_Book_id seq/auto,
User_id int, –pk
PrimaryBookmark int, –an offset?
BookMarkTypes
BookMarkType_id seq/auto,
BookMarkTypeName varchar(100), — in Primary, DogEar, Highlight
BookMarks
BookMark_id seq/auto,
BookMarkType, –pk
BookMark int –an offset?
BookMarkColor

Off to put that into real PostgreSQL DDL.

Time: 8:20pm

Time: 8:25pm
On second thought I should normalize Authors out of GutIndex. Author is now a foreign key to an Authors table. Now if we want to keep details about Authors, that is a little easier. I will not handle the case of books having multiple authors at this time. For now, Authors will be listed in the Authors table again if they published a book with another author. e.g.:
Joe Blow – The Hard Knock Life
Joe Blow and Terry Harry Berry – The Knock ‘Em Hard Guys.

It would be nice to have an N-to-N relationship between books and authors, but for right now, I will only have a N-1 relationship, so Joe Blow and Terry Harry Berry will be an entry in the Authors table separate from Joe Blow. This will make parsing GUTINDEX.ALL easier for now.

Time: 8:29pm

Time: 8:47pm
I’m alsmost done with the DDL. I’m just looking up how to switch users and databases in PostgreSQL. The first loaf of bread went into the oven. I forgot to preheat, that is why it is going in so late. Next loaf goes in at 9pm.

Time: 9:35pm
First loaf is out, and I’m stuck with not being a DBA. I’m dealing with some PostgreSQL permissions because I want to do things right with a DB Owner user for the DB piece. I’m also dealing a bit with case issues in rails. Apparently if you generate a model or controller with uppercase letters, rails changes them to lower case, but separates them with an underscore, so BookStatus became book_status. Whatever OR mapping Rails does then proceeded to look for a table called book_status, but my table is called bookstatus. PostgreSQL table names are not case sensitive, so even though in my pretty looking definition I call it BookStatus, a listing of database objects reveals all lowercase names. Same is true for PostgreSQL users, databases, and probably all objects, so configurating password auth took more time than it should have. I’m not sure why PostgreSQL doesn’t just lower() everything. Ignoring my lines in pg_hba.conf because of upper case characters was a bummer. Not being able to login with an username containing upper case characters was also a bummer. I should mention I’m using PostgreSQL 7.4 because it is what I happen to have on my Ubuntu Breezy (pre-release) system.

Back to hammering out the PostgreSQL permission issues. Seems like I go through this every time.
Time: 9:41pm

Time: 10:10pm
Ugh, I just found Really Getting Started In Rails where it mentions specific rules for naming things. All Primary Key columns in my tables should be named “id”, and foreign key columns should be named tablename_id. That is fine, its just not what I prefer. I’ll go change my column names.

I’m still not quiet sure how to model the concept of Users with ruby. I’m leaning toward having a Users controller which assumes a Default User and using that user until a visitor logs in by accessing a Users/login target. Hopefully I can find a good example.

Time to cut the bread. It smells delicious and Janice (my wife) keeps asking if it is ready.

Time: 10:14pm

Time: 10:50pm
I did some database redesign after reading more rails docs. ClassMethods for Associations is important stuff.

I’m getting tired I can tell I’m not as focused as I would be in the morning. The bread is delicious. It is some of the best bread I’ve made yet. It is about time to cut the second loaf.

With a little more than an hour to go, it doesn’t seem like I’ll be getting very far in my little experiement, but I’ve learned a lot about Rails. That was kind of the point.

Time: 11:12pm
I found Rails Cookbook with exactly the kind of authentication required example for which I am looking. I’ll have to review it to see what kinds of implications it has for my current design.

The second loaf of bread is delicious. I was going for honey wheat, but it didn’t come out that sweet. It is some damn good bread though. I’ve had two pieces of each kind. That is a lot of bread.

Time: 12:00pm

No, I didn’t have a time set, I just found LoginGenerator and figured I could blog on that and call it a night. The time just happened to be midnight when I checked it.

4.5 hours later, I don’t have anything near an application. All I have are a bunch of screwed up Model and Controller files, and a whole lot more Rails knowledge. The Login Generator definitely looks cool. I’ll definitely be trying that out soon.

The Authors login example from the Rails cookbook works, but has an annoying bug that if you login incorrectly, it redirects indefinitely. I’m not sure why the authenticate action is being called on redirect_to action=>”index”, but it is. Hopefully this Login Generator will help.

Time: 12:13pm
Major Bummer. It seems Login_Generator is an optional addon to rails to be installed via Gem. Ubuntu doesn’t package gem nor Login_Generator. So my options are to build ruby from source, or figure a way to package it. I’m leaning toward the later for the benefit of all ubuntu folk, but it won’t be tonight.

installing lxr and configuring for gnome lxr using Ubuntu breezy

the lxr package uses glimpse for search. glimpse is not free, so we use the lxr-cvs package. This uses swish-e and a PG/MySql/Oracle/AnythingDBI backend.

install the lxr and the swish-e packages – I’m not sure why the lxr-cvs package is there, or why it exists. Looks like it is moving to a database backend which may be faster?

checkout the source cvs you want to use. I grabbed gnome in an evil way like this

for module in `cvs -z5 co -s | cut -d ' ' -f 1 ` ; do cvs -z5 co $module ; done

configure lxr.conf with proper directories and versions and stuff. The version part is stupid because it assumes you have a dir with subdirs of versions. If you just want to index 1 dir, use its parent as sourceroot and the dirname as version.

  • create postgresql db and user
  • configure the database for password auth
  • initialize the database for use with


createdb lxr ; createuser -A -D -P lxr # then type the password when prompted
echo local lxr all md5 >> /etc/postgresql/7.4/pg_hba.conf
invoke-rc.d postgresql-7.4 restart
psql -U lxr -f /var/lib/lxr-cvs/initdb-postgres lxr

then run lxrgen

cd /var/lib/lxr-cvs ; ./genxref --url=http://localhost/lxr

working around a “secure” build of windows

At work they have these stupid windows images to install from, rather than default installs. One of the side effects is that I cannot drag and drop in Windows Explorer.

Here is my fix and undo of “security” to enable drag and drop in windows.

This is just a copy and paste of information I found in a forum somewhere. It seems the change must be made and you must logoff/logon (or maybe just restart explorer.exe).

Good, then we can try two other remedies. I am assuming by the way that you are not receiving any error messages during your attempts to drag and drop.

1. Check your settings in DCOMCNFG.

This is based on MS KB Q274696: http://support.microsoft.com/default.aspx?scid=kb;en-us…

For XP the modified solution is to open dcomcnfg, go to the properties page for Component Services | Computers | My Computer, go to the Default COM Security page, under “Access Permissions” click “Edit Default” and make sure that the local SYSTEM and INTERACTIVE users have “Access Permission” with the “Allow” checkbox checked.

2. Re-register some DLLs.

Start, Run, and either type CMD and paste the below as a box into the CMD session, or enter each line one-by-one:

regsvr32 urlmon.dll
regsvr32 Shdocvw.dll
regsvr32 Msjava.dll
regsvr32 Actxprxy.dll
regsvr32 Oleaut32.dll
regsvr32 Mshtml.dll
regsvr32 Browseui.dll
regsvr32 Shell32.dll
regsvr32 riched20.dll

TekTippy4U (TechnicalUser)
7 Aug 04 3:46
hi folks;
couple of quick points;
[…as the long tooth becomes a fang ]
I’m not up on current MSOffice DLL versions, and associated apps, nor with all XP DLLs per se — so some DLLs below may be older – feel free to update with the correct file name.
[1] I’m inclined to think it’s related to an unregistered DLL ( improperly registered or overwritten/replaced, and even perhaps an OCX that needs re-registering – thinking an Explorer issue more-so than an IE one).
along these lines – I’d like to add a few to the list (that bcastner already posted);
regsvr32 Comctl32.dll
regsvr32 Shlwapi.dll
regsvr32 User32.dll
regsvr32 User.dll
regsvr32 Olepro32.dll
regsvr32 Ole2.dll
regsvr32 Ole2conv.dll
regsvr32 Ole2disp.dll
regsvr32 Ole2nls.dll
regsvr32 Ole32.dll
regsvr32 Olecli32.dll
regsvr32 Olecnv32.dll
regsvr32 Olesvr.dll
regsvr32 Olesvr32.dll
regsvr32 Olethk32.dll
regsvr32 Oleacc.dll
regsvr32 Setupwbv.dll
regsvr32 Softpub.dll
regsvr32 Wininet.dll
regsvr32 Wintrust.dll
(sorry bout the long list, but might as well try em all – and depending on which version of IE you’re running these files will vary, and you’ll definitely get some errors when trying to register them all).

The other quirky thing about this, is that you’d think that an SFC /Scannow would restore the Original DLLs – if some are wrong versions or have been maliciously replaced by malware (as certain usual Windows files can and are – such as rundll32.exe and regedit.exe and notepad.exe to name a few).

[2] Someone will have to follow up on the OCX theory, kinda like the way exoticspice’s faq lists entries to the Interface Key – perhaps it’s a TypeLib prob. I think the OCX files may need the full path listed in the command?

[3] I’ve heard of anomalies with drag-n-drop and cut and paste from having more than 1 Keyboard Language set in the Keyboard Properties > Language tab of Control Panel.

[4] Finally….anyone think this is an Accessibilty Setting option gone awry?

……oh well – a shot in the dark anyway.

TT4U

Notification:
These are just my thoughts….and should be carefully measured against other opinions.
Backup All Important Data/Docs

follow up to gnome-session complaints

http://little.xmtp.net/blog/2005/08/28/stupid-code-aka-gnome-session-phantoms/

I posted some crap about issues I have been having with gnome-session. Well, the stupid error message is still there. The solution to my problem was as easy as using a Mac.

System->Preferences->Sessions. Delete the default session. Logout. Login. A new default session will be created. There will be no stupid long delay.

Sadly I went through the exercise of checking out gnome-session, diving into source, and enabling GSM_VERBOSE_DEBUG=true to read more output in .xsession_errors. One of the errors finally gave me this idea.

Anyway, thinks are better now. I am a happy Ubuntu Gnome user.

RE: Spot the Bug – August 14, 2005

I created this bug a couple of weeks ago for a conference I spoke at to illustrate how so few lines of code could be so buggy. Where’s the bug here?

char dest[50], src[100];
int x, y;

if (x=1)
{
strcpy(dest,src);
dest[50] = ‘\0’;
}

return y;

Solution:
Alright, so I admit it — this chunk of code is a bit nonsensical. But I will say that people do make these mistakes all the time, but probably not all at the same time. 🙂

This code has 4 security defects:
1. The if statement with “=” instead of “==”. Many of you would argue that this is of a quality issue than a security issue, and you’d be right. But security is certainly a subset of quality, and this can cause the code to do things that it shouldn’t do.
2. In strcpy, src is larger than dest, causing a buffer overrun.
3. Arrays start at 0, not 1! Therefore, we are writing past the last allocated spot on the array.
4. The variable y is not initialized.

Now that you’ve heard the bad news about all that’s wrong with this code, it’s time for some good news. I bet you didn’t know that Visual Studio 2005 catches all of these problems! Strcpy is caught by the compiler and noted as a warning. We’ve created safe versions of these libraries in Visual Studio 2005 called Safe CRT libraries. PREfast catches the other 3 bugs — even the “=” error. With these tools and proper education, we hope to get developers all over the world wrting more secure code!

 

[Via Spot the Bug!]

The part that I find exciting is that the compiler catches all of these problems. This is excellent. I’m not sure of that status of GCC in this regard, but given GCC development over the past few years, I’ll bet it is either already there, or coming real soon now.