|
|
Monday, August 4. 2008
[...] a good programmer cultivates the virtue of laziness. (But not just any laziness: you must be aggressively, proactively lazy!)
-- Chris Pine, dealing with the DRY rule
Saturday, July 12. 2008
Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning.
-- Richard Cook, read on FSM
Sunday, July 6. 2008
[...] as we all know, premature optimization is the root of all evil.
-- from a cocoa-dev email
amen!
Wednesday, June 4. 2008
Suppose you want to create an application which you want to limit to a single running instance, like some image viewers do for example. Also, you need different users on a Terminal Server not to conflict with each other. Oh, and you're coding in C#.
A possible solution to the problem is the one described in this Flawless Code post.
What I didn't like is, it requires the 3.5 version of the framework, while I preferred to be able to run on machines with only 2.0 installed. So I've replaced the NamedPipeClientStream/NamedPipeServerStream with a P/Invoke-based implementation based on this example.
Also, I create a different pipe per user session, since I haven't found a way to create a "local" pipe. An article at Dr Dobb's suggests that it's possible, while MSDN doesn't mention this possibility...
I've zipped up my test solution in case someone else has the same needs.
Monday, June 2. 2008
I've just added LogMiner to Ohloh, a site that offers an interesting feature: it can analyse a project source code and estimate how much it would cost to hire a development team to recreate the project from scratch.
I think that it's a simple way to estimate the effort you put over the time in open source projects.
Here's the resulting figure for LogMiner:
Monday, May 19. 2008
Here's another interesting piece of code I've just digged up in a C# application I'm reviewing.
If you can come up with a bright idea about what those try/catch blocks are supposed to do, you've got more imagination than me...
class Foo { private int bar;
// ...snip...
public int GetNewBar() { int ret = 0;
lock (this) { try { bar++; ret = bar; } catch { try { bar++; ret = bar; } catch {} } }
return ret; }
// ...snip... }
Wednesday, May 14. 2008
Sometimes when you're reviewing someone else's code, you find interesting pieces of " art". Like the following loop construct in a C# application:
int i = anArray.Length - 1;
while (true) { if (i < 0) break; else { ... i--; } }
Doh.
You might be tempted to rewrite it as:
for( int i = anArray.Length - 1; i >= 0; i-- ) { ... }
but it would be too simple, too boring, wouldn't it?
Friday, April 18. 2008
I always assumed the designers of the Objective-C language and Cocoa frameworks trust me to know what I'm doing while I find very elegant ways to shoot myself in the foot.
-- from a mail sent to Cocoa-dev
Thursday, January 24. 2008
When you design a complex application, it's always useful to separate the presentation layer from the business logic. Usually, when dealing with web apps, this involves handing templates which are "filled" with data by your controller.
The common rationale is that the template should contain as little logic as possible and that it should be easily editable by non-programmers.
There are several PHP packages (Smarty, PHPTal, etc...) that aim at providing a flexible and neat template framework. They usually try to force you not to put code in the template by providing a limited set of directives that can be used, such as placeholders, foreach-style control blocks, conditional blocks... but in the end, every framework I've seen also includes a directive that allows you to put arbitrary PHP code inside the template.
Thus I've always wondered: what's the point? Why don't you just use PHP as a templating engine instead of inventing a new language?
So, let me introduce my super-duper template class!
<?php/* * Copyright ©2007-2008 by Simone Tellini * http://tellini.info/ */class Template { private static $commonVars = array(); private $tpl; private $vars; public function __construct ( $template ) { $this-> tpl = $template; $this-> vars = self:: $commonVars; } // you might set some variables before instantiating your templates when // you want to have some data available in all the templates you need to // build a complex page public static function setCommon ( $key, $value ) { self:: $commonVars[ $key ] = $value; } public function set ( $key, $value ) { $this-> vars[ $key ] = $value; } public function execute () { $T = $this-> vars; ob_start(); include( $this-> tpl ); $html = ob_get_contents(); ob_end_clean(); return( $html ); }}?>
Ta-da!
A sample template may look like:
<html> <body>
Hello, <?= $T[ 'user' ] ?>!
</body> </html>
The $T array is the only variable visible to the template (except for $this, which points to the Template instance and the super-variables $_GET, $_POST, etc...), since it's the only variable defined in the scope where the template has been include()'d
The controller might look like this:
<? require_once( 'classes/template.php' ); $tpl = new Template ( 'templates/helloWorld.php' ); $tpl-> set( 'user', 'World' ); print( $tpl-> execute() ); ?>
I've been using a class like that for a couple of years now, without any regret. It's been used in sites whose content and graphics are now constantly edited by their owners: even though they aren't programmers, they never had any problem whatsoever in editing or creating their own templates. I truly like it beacuse:
- it's simple
- it surely isn't bloated
- it's faster than many (most?) of the other templating engines
- it's as flexible as you need
Of course, the fact that you're using PHP to create your templates shouldn't tempt you to start placing business logic inside them!
Sunday, January 13. 2008
After a long exposure to .NET, when I get back to PHP I sometimes find myself missing some cool functionality (and a good IDE too... none of those I've tried so far can compete with the comfort of VisualStudio + ReSharper).
Among these missing features, attributes are what I needed in order to solve a certain problem in an elegant way.
Looking at what the reflection API was offering, I came up with a simple way to decorate my properties/methods/classes with attributes: through the documentation comments!
Let's see an example:
<pre> <?class A { /** * @attr * @attr2 */ protected $foo; protected function GetPropAttrs ( $property ) { $class = new ReflectionClass ( get_class( $this )); $prop = $class-> getProperty( $property ); $doc = $prop-> getDocComment(); $attrs = array(); $matches = array(); preg_match_all( '/@([a-zA-Z_][a-zA-Z_0-9]*)\s/m', $doc, $matches, PREG_SET_ORDER ); foreach( $matches as $m ) $attrs[] = $m[ 1 ]; return( $attrs ); } public function test () { $attrs = $this-> GetPropAttrs( 'foo' ); print_r( $attrs ); }}class B extends A { /** * @attr3 */ protected $foo; }$obj = new A (); print( 'Test A:<br>' ); $obj-> test(); $obj = new B (); print( '<p>Test B:<br>' ); $obj-> test(); ?></pre>
Running the above script you'll see the following output, confirming that everything works as desired:
Test A:
Array
(
[0] => attr
[1] => attr2
)
Test B:
Array ( [0] => attr3 )
If you're using the /** */ comments for real documentation, you might want to use another escape character rather than @, to avoid problems.
Happy coding
Friday, January 4. 2008
I think so.
Why? Because it's basically a toy DBMS with too many non-standard behaviours.
A lot of open source projects choose MySQL mainly because it's widely available among hosting providers, while better RDBMS like PostgreSQL1 are hard to find. The real problem is, a lot of open source developer know very little about SQL and databases: they make things up as they proceed in their project, almost often caring only that "it works" for them 2. The result is that they learn wrong habits and write poor DB-related code, a trait common to many projects, sadly.
For instance, the inspiration for this rant comes from this bug report for Flyspray, a bug reporting system written in PHP. The report is about a pretty lame error in the SQL query used to fetch the task list, as detailed in the 9th comment. PostgreSQL is not "incredibly annoying regarding GROUP BY" as the Flyspray maintainer believes: PostgreSQL simply does the right thing to do in that case, just like every other serious 3 RDBMS on the market. I was recently hired to port Flyspray to Oracle: needless to say that I had to fix this problem as well as several other queries.
Other examples of DB abuse include Mantis, another PHP bugtracker. If you had a chance to use it, probably you've seen the statistics at the bottom of the page, something like:
43 total queries executed.
30 unique queries executed.
I beg your pardon? 43 queries to display a 10 rows table? and why 13 of them have been performed twice?
So, please... kids don't use MySQL at home.
I'm not saying that you should never use MySQL (there would be plenty of reasons to avoid it anyway  ) or that projects based on it suck (I like mantis, for one). It's simply a bad choice for a beginner wishing to learn how to do things properly, IMHO.
1 my favorite open source RDBMS. If it seems like I'm doing some advocacy, well... maybe I am 
2 I've got nothing against this attitude when it comes to free software: if you want things to get done as you wish, you should be prepared to do them yourself or pay for them, instead of expecting other people to do the dirty work for free 
3 yes, that excludes MySQL 
Saturday, December 8. 2007
John Engelhart posted to Cocoa-dev a detailed explanation of what exactly const means in C programs.
Keep in mind that he's talking about C, not C++ (where const has a stronger meaning and even a slightly different semantic when used to declare constant values).
Still, it's worth reading.
Wednesday, October 3. 2007
The .NET Framework 2.0 contains a component called ReportViewer which can be used to generate reports in different formats (HTML, PDF, etc...).
After having used it for a couple of reports in a web application, I came to believe that the only good thing about it is that it's free (when used in Local mode).
Why? Because of its bug ridden designer!
First of all, it contains a nice "Data Sources" panel that should list all the functions (from your code) that can be used to feed the report. Wonderful. Too bad that unless you keep the Default.aspx page open it doesn't display anything.
Also, you should place the .rdlc file in your App_Code folder to get the "Data Sources" list to work. Too bad that when you publish your web site, the content of that directory will be ignored.
There are other bugs here and there, but come on... how can these two have not been noticed by Microsoft?
Friday, May 25. 2007
In this second post about my preferred coding style, I'll talk about white space.
White space is very important to improve readability, not only when dealing with code. For instance, when you write an email you usually break it up in several paragraphs, instead of writing a single chunk of code (or if you don't, you should!).
When writing a piece of software, white space should be used to isolate code blocks logically and to enhance the visibility of the most important parts of the code (e.g. arguments, operators, operands...).
I often see people writing code like this:
void foo() {
string bar = "a";
string row = "";
foreach (ObjectType item in collection) {
Response.Write("zot!");
AnotherMethodCall();
abc = dtMinData;
row = i%2==0 ? "even" : "odd";
// ...
It's not very pleasant to the eyes (and I've seen worse than that!). Let's pimp it up!
1. void foo()
2. {
3. string bar = "a";
4. string row = "";
5.
6. foreach( ObjectType item in collection ) {
7.
8. Response.Write( "zot!" );
9. AnotherMethodCall();
10.
11. abc = dtMinData;
12. row = (( i % 2 ) == 0 ) ? "even" : "odd";
13.
14. // ...
Some notes:
- line 1-2: as I've said in my previous post, I hate the java-style
Line 2 helps to separate the method name from the first line of code, so they're both easier to see.
- line 5 is empty, to mark the end of the variable declaration block and the beginning of a statements block.
- line 6: notice the spaces inside the parenthesis, to increase the readability of the content of the foreach(). There is no space between foreach and the opening parenthesis, for two reasons: 1. the parenthesis is part of the instruction, not of its arguments 2. syntax highlighting makes the foreach keyword already enough visible.
- line 10 is empty, stressing the passage from a series of method invokations to a block of assignments.
- line 12: what?! no whitespace around operators? Also, even if the language in this case doesn't require them, I prefer to use parenthesis to explicate the structure of the expression.
Saturday, May 19. 2007
Writing software is an art: some say it's a black art (usually right after Word decided to crash taking their last two hours of work to hell  ). Someone even considers it a magic art, which reminds of an Arthur Clark quote: "Any sufficiently advanced technology is indistinguishable from magic".
Like other arts, it has its canons: rules, principles that define how a piece of software should be written. In this post, I'm talking about the style, not the language. Every software developer seems to have his own set of rules: I usually end up arguing with everyone about them
I've decided to write this post, and hopefully other ones, to explain my coding style and the rationale behind it, especially in the vain effort to get my colleagues to agree with me  or at least, to comment with their point of view.
Let's start from the dogma:
Code should be easy to read
I do mean "read", not necessarily "understand": it's hard to understand something if you find it difficult to read.
You should be able to pick up a piece of code written by someone else and scroll through it grasping its structure at a glance, without having to read every single word or character. You might be looking for a single spot to fix in a huge file and you don't really want to stay overtime just to find it.
This has always been my #1 rule and it's usually the first answer I give when someone asks me "why the heck do you write declarations like that, functions this way and expressions that way?"
Let's see now how my coding style it's just an application of the dogma.
Namespaces, classes and methods
I write all these structures using the same style:
- the first line declares the block
- the opening brace is placed in its own line. The content of the block begins in the following line, without any blank line in between
- the closing brace is placed in its own line, without leaving blank lines after the last line of the block
Example:
class Example
{
public void Method()
{
int n;
// ...
}
}
I don't like the Java-style, which is preferred by someone at the office. Why? Because it forces the eye to do more work to recognize the important part of the text: the name of the namespace/class/method.
For instance, look at the following two examples and try to identify the methods as quickly as possible, while scrolling the page up or down:
public void which() {
ThisMightBeAnother declaration;
ThisIsAnother.Kind ofObject;
// ...
}
public void isTheMost() {
DontGetDistracted lookOnly;
atTheMethod names!
// ...
}
public void easyToRead() {
DontGetDistracted lookOnly;
atTheMethod names!
// ...
}
...
public void between()
{
ThisMightBeAnother declaration;
ThisIsAnother.Kind ofObject;
// ...
}
public void thisAndThe()
{
DontGetDistracted lookOnly;
atTheMethod names!
// ...
}
public void previousExample()
{
DontGetDistracted lookOnly;
atTheMethod names!
// ...
}
...to be continued...
|
|