published 8 minutes ago (12.05.2008 11:33)

Allowed Interactions in Robustness Analysis Diagrams

i think these are the sexiest uml diagrams by far :-)

Posted in  | Tags ,  | no comments | no trackbacks

published 19 days ago (23.04.2008 18:03)

Firefox 3 uses sqlite to store bookmarks (and most other things)

ever wanted to search your bookmarks with

SELECT * FROM moz_bookmarks WHERE title LIKE "%ruby%";

now you can:

in your firefox profile directory (~/Library/Application Support/Firefox/Profiles/xxxx.default on a Mac), type:

# open db file
$ sqlite3 places.sqlite

# show available tables
sqlite> .tables

# set output to sql insert statements
sqlite> .mode insert

# send output to file "firefox_bookmarks" 
sqlite> .output firefox_bookmarks

sqlite> SELECT * FROM moz_bookmarks WHERE title LIKE "%ruby%";

# list other available commands & options
sqlite> .help

Or, if you want JSON output you can export all bookmarks via the GUI. Use Bookmarks > Organize Bookmarks, click the rightmost icon in the top navigation and choose Export.

Posted in ,  | Tags , , ,  | no comments | no trackbacks

published 5 months ago (16.12.2007 19:21)

Sapir-Whorf Hypothesis

“The Sapir-Whorf Hypothesis theorizes that thoughts and behavior are determined (or are at least partially influenced) by language. […] To this day it has not been completely disputed or defended, but has continued to intrigue researchers around the world.”

Posted in , ,  | no comments | no trackbacks

published 6 months ago (24.11.2007 20:39)

Firefox LiveHTTPHeaders bugfix for Alt-L / @

the firefox LiveHTTPHeaders extension is a great tool for monitoring the http requests going on between your browser and a server—ideal for debugging requests or optimizing caching.

however, the extension has a small but very annoying bug, especially on Mac OS X. it’s sidebar shortcut is Alt-L, which is already occupied by the @ sign. so with this extension installed, you can’t type @s anymore. aaarrgh!

the bug is already (somewhat) fixed in CVS, but it doesn’t look like there’ll be an official release anytime soon. so i dove into the code, did the bare minimum to fix the problem, and made a new xpi. install the patched extension here: livehttpheaders-cvs-patched-071124.xpi.

i moved the sidebar shortcut to Shift-Cmd-J. ”!!?$ Shift-Cmd-J ???!!”, you ask?
“why from Alt-L to Shift-Cmd-J?” well, first, the CVS version already moved the command to Shift-Cmd-L. good. unfortunately Shift-Cmd-L (and Shift-Cmd-K) are already used by the firebug extension, so i moved the key leftwards to the first unoccupied one.

as mentioned above, i did the bare minimum to get the extension to work. no perfection here … but i hope it works for you, too!

Posted in , ,  | Tags , , , ,  | 1 comment

published 6 months ago (11.11.2007 15:04)

"The suits people are surrounding us."

—Matz, on Ruby becoming “Enterprisey” (via project.ioni.st)

that’s almost a shock, makes me afraid. but he’s right—at last railsconf europe for example, sun, ibm & co showed up. pushing their tools, and ideas of “how to develop”, without any deeper knowledge of ruby. let’s hope they’ve learnt or are willing to learn, and aren’t just disguising just to enter this market and sell their stuff to people who can’t tell the difference.

make sure ruby and the community stay the way they are, it’s what’s makes it special, and what made it successful.

Posted in ,  | no comments

published 7 months ago (07.10.2007 14:02)

so what's duck typing?

duck typing is actually a simple concept. the best explanations i have come across (from wikipedia 1, 2):

»Suppose you see a bird walking around in a farm yard. This bird has no label that says ‘duck’. But the bird certainly looks like a duck. Also, he goes to the pond and you notice that he swims like a duck. Then he opens his beak and quacks like a duck. Well, by this time you have probably reached the conclusion that the bird is a duck, whether he’s wearing a label or not.” (Immerman 1982, p. 102)«

So, in programming, duck typing is a style of dynamic typing in which an object’s current set of methods and properties determines the valid semantics, rather than its inheritance from a particular class, or implementation of a formal interface.

The ruby mailing list has a great post called ”How to duck type? - the psychology of static typing in Ruby”, explaining the rationale and why duck typing is a good thing (in ruby). an excerpt:

»Many people coming to Ruby from a statically-typed language are somewhat afraid of Ruby’s dynamism, or “don’t get it(TM)”. David Black and I (edit: Tim Bates) believe that this is in part because it is thought that the uncertainty and changeability built into Ruby are dangerous and one wants to find shelter from them.«

Posted in ,  | Tags , ,  | no comments

published 8 months ago (09.09.2007 16:06)

refactoring five year old javascript code to use the prototype.js library

i’ve long been skeptical of javascript libraries. web 1.0’s myriads of “dhtml” / cross browser libraries didn’t improve the javascript programming experience much. at least there was no library i found so useful that i’d use it in all my projects. so all i had was a couple of snippets picked up here and there, like addEvent() / removeEvent() by the good ole Scott Andrew.

web 2.0 brought a lot of new buzzwords, and more frontend fun. and frontend fun requires: new javascript libraries! fortunately, these libraries seem to be different:

  • they are professionally written, complete with unit-tests
  • their developers don’t have to waste their time coding for horribly bad, pre-DOM browsers (Netscape 4, IE/mac anyone?).
  • they are better integrated in the core of the language
  • their developers have learned from their and other’s experience
  • there are a handful of popular libraries that have been widely adopted, which are continuously developed and improved, producing high quality, reliable code.
  • they focus on developer productivity, instead of eye-candy and supplying drop-in high-level components
  • computers have become faster, allowing to write code that makes developers more productive, although it requires more cpu

ENTER PROTOTYPE.JS

as an experiment, i wanted to refactor a web page i created in 2002, thomasgraggaber.com, to use a current javascript library. since i’ve already used prototype.js, the library is well-established, well-documented, robust (and bundled with ruby on rails), i decided to use it for the experiment.

so here are the stats for the “application” javascript, i.e. everything that’s specific for the site:

  • original lines of code: 571 (65 of them in cross-browser helper methods)
  • lines of code after refactoring to use prototype.js: 445. that’s 22% less code.
  • the cross-browser helper methods were “library code” as well. ignoring those it’s still 10% less code.

of course you add 3271 lines of code for prototype.js (in v. 1.5.1). what’s important however: you usually don’t have to maintain, debug and completely understand the internals of prototype.js when creating your application.

the major code changes are:

Iterators, $$ and Event.observe

before:

var allDivs = document.getElementsByTagName('DIV');
for (i=0; i < allDivs.length; i++) {
    // ...
    else if(allDivs[i].className == 'sidebar')
    {
        addEvent(allDivs[i],"mouseup",dragManager);
        addEvent(allDivs[i],"mousedown",dragManager);
    }
    // ...
}

after:

$$('.sidebar').each(function(div) {
    Event.observe(div, 'mouseup', dragManager);
    Event.observe(div, 'mousedown', dragManager);
});
  • $$() is the swiss army knife for selecting elements in a document. give it a css selector and it will return all matching items in a collection. it probably isn’t the most efficient thing to use, but fine here, and is short. prototype’s document.getElementsByClassName() could also have been used.
  • the temp variable allDivs can be removed, since the iterator function #each works with the result of $$’s return value directly.
  • Event.observe is prototype’s way of registering an event handler cross-browser.

another example. nothing new here, but it takes even more advantage of the iterators:

// photosThumbs viewer
var photosThumbsNodeList = contentDivs['photosThumbs'].getElementsByTagName('IMG');
for (i=0; i < photosThumbsNodeList.length; i++)
{
    addEvent(photosThumbsNodeList.item(i),"click",photoManager);
    addEvent(photosThumbsNodeList.item(i),"mouseover",photoManager);
    addEvent(photosThumbsNodeList.item(i),"mouseout",photoManager);
}
var newsThumbsNodeList = contentDivs['news'].getElementsByTagName('IMG');
for (i=0; i < newsThumbsNodeList.length; i++)
{
    addEvent(newsThumbsNodeList.item(i),"click",photoManager);
    addEvent(newsThumbsNodeList.item(i),"mouseover",photoManager);
    addEvent(newsThumbsNodeList.item(i),"mouseout",photoManager);
}
var portraitThumbsNodeList = contentDivs['portrait'].getElementsByTagName('IMG');
for (i=0; i < portraitThumbsNodeList.length; i++)
{
    addEvent(portraitThumbsNodeList.item(i),"click",photoManager);
    addEvent(portraitThumbsNodeList.item(i),"mouseover",photoManager);
    addEvent(portraitThumbsNodeList.item(i),"mouseout",photoManager);
}

becomes

// photosThumbs viewer
$w('photosThumbs news portrait').each(function(divName) {
    $$("div#" + divName + " img").each(function(img) {
        $w('click mouseover mouseout').each(function(eventName) {
            Event.observe(img, eventName, photoManager);
        });
    });
});
  • $$() is used again. it could be replaced by “$A($(‘border’).getElementsByTagName(‘div’))” if it gets too slow.

the $w function

before:

// add event handlers
var naviDivs = document.getElementById('border').getElementsByTagName('DIV');
for (i=0; i < naviDivs.length; i++)
{
    addEvent(naviDivs.item(i),"click",ggNaviManager);
    addEvent(naviDivs.item(i),"dblclick",ggNaviManager);
    addEvent(naviDivs.item(i),"mouseover",ggNaviManager);
    addEvent(naviDivs.item(i),"mouseout",ggNaviManager);
    addEvent(naviDivs.item(i),"mousedown",ggNaviManager);
    addEvent(naviDivs.item(i),"mouseup",ggNaviManager);
}

after

// add event handlers
$$('div#border div').each(function(naviDiv) {
    $w('click dblclick mouseover mouseout mousedown mouseup').each(function(eventName) {
        Event.observe(naviDiv, eventName, ggNaviManager);
    });
});
  • $w is a nice adoption from ruby (where it’s %w). it splits the string argument by whitespace, returning an array of the items (“words”). very readable in this case.

Event.element(e), and returning only element nodes

e = (e) ? e : ((window.event) ? window.event : '');
eTarget = e.srcElement ? e.srcElement : e.target;   
while(eTarget.nodeName != 'DIV') {
    eTarget = eTarget.parentNode;
}

becomes

eTarget = Event.element(e);

nice.

  • prototype handles finding the event target in a cross-browser way. (note: prototype 1.6.0 will make this even simpler. the event handler will be bound to the event target, so the event target will be available in the “this” variable.)
  • prototype only returns element nodes, so the while() loop looking upwards for a div element becomes obsolete. it was required since it’s possible that the text node inside the element was clicked. this behavior allowed removal of a couple of these loops.

“DOM walking” with up(), down()

scrolledDiv = first_child(node_after(eTarget.parentNode.parentNode));

becomes:

scrolledDiv = eTarget.up('.box').down('.content')
  • firstchild() and nodeafter() were some of the utility methods to walk through the DOM, and already ignoring whitespace and text nodes. element.up(…).down(…) do the same, but are nicer, shorter, clearer to use.

show() and hide()

before:

function displayNavi()
{
    document.getElementById('sponsorFlash').style.display = 'none';
    document.getElementById('border').style.display = 'block';  
}

after:

function displayNavi()
{
    $('sponsorFlash').hide();
    $('border').show();
}
  • the code becomes more concise, and more expressive.
  • i don’t have to remember which elements require which display style in order to be displayed correctly (block/table/inline elements have different values).

conclusions

  • by using prototype.js i was able to remove 10% of the code
  • at the same time, the code is more readable than before
  • as an additional benefit, the site now probablyworks in safari (and all browsers that prototype supports)!

prototype.js rocks, because it’s developed by smart people, and because javascript itself rocks!

Posted in ,  | Tags , , , , ,  | no comments

published 9 months ago (11.08.2007 16:32)

25 german startups, and their technology choices

jetzt.de (the “youth” magazine of the süddeutsche zeitung) gives an interesting overview of 25 current german startups, asking every one of them around a dozen questions.

greenmiles.de

i found the greenmiles.de idea particularly interesting: you enter your planned trip and transportation type, then they calculate how much co2 is produced. you can then donate an appropriate amount of money to climate conservation programs, allowing you trip to be climate neutral. of course very rough, but nevertheless interesting feedback on how much co2 one of us produces in his day to day life. for example, one round-trip flight hamburg-munich produces 9m³ of co2, which equals a cost of 8 euros.

german startup technology choices

i was curious which technologies these startups would consider best for their success, so i looked at the programming languages and frameworks they used. here are the results:

60% php
16% ruby (= ruby on rails)
16% java
4% asp.net
4% (project offline)

a couple of observations:

php & java have been at the availability of web developers since at least 1999 (that’s when i started) and ruby on rails had it’s 1.0 release in december 2005. so i can only say: go rails! :-)

so let’s say konichiwa to these ruby on rails projects:

looking at php

of course with 60%, php is the most important language by far. it’s the technology one needs least development experience for, and it allows fast results; therefore very appealing. working with less experienced developers however also means things can go really bad down the road – remember the studivz scalability and security issues, for example. and still not all of the startups seem to do their php development in a professional way. some use a CMS (typo3) as a base for their site, others still run php version 4, which has been replaced by php5 three years ago and is now discontinued.

there is only rails

the java and php projects use a variety of frameworks, but in the ruby projects – there is only rails. that’s good – a ruby web developer will almost certainly know how to work with rails. a php developer will more than likely not know how to work with your framework, since there are so many open source php frameworks out there, and still many people roll their own one.

on a side note, only one startup runs on microsoft technology …

i figured out what a site runs by looking at their webserver’s responses (server type, cookie name) and the generated html. if in doubt i checked their tech jobs postings, too. for the technically inclined, here’s the full list:

dealjaeger.de java spickmich.de php cellity.com java (jboss) autoaid.de php (symfony) AND/OR python hitflip.de php verwandt.de php amiando.de java dawanda.de ruby on rails (/w mongrel server) hiogi.de php zeitkapsel.de php wazap.de java schutzgeld.de php (typo3) frazr.de php rankaholics.de php sevenload php imedo.de ruby on rails (/w mongrel server) globalzoo.de php greenmiles.de php (typo3, still php4!) jajah.com asp.net mitbringzentrale.de – (offline) mymuesli.de php (still php4!) qype.de ruby on rails (/w lighttpd server) spielerkabine.de ruby on rails (/w lighttpd server) edelight.de php studivz.de php

Posted in , ,  | no comments

published 12 months ago (18.05.2007 12:26)

some bash shell tricks

phillipoertel@[~]: cd Documents/seaside/
phillipoertel@[~/Documents/seaside]: cd -
/Users/phillipoertel
phillipoertel@[~]: a b c
-bash: a: command not found
phillipoertel@[~]: !$
c
-bash: c: command not found
phillipoertel@[~]: a b c
-bash: a: command not found
phillipoertel@[~]: !!
a b c
-bash: a: command not found
phillipoertel@[~]: a b c
-bash: a: command not found
phillipoertel@[~]: !*
b c
-bash: b: command not found
phillipoertel@[~]: 

see also: nubyonrails.com

Posted in  | no comments

published 12 months ago (18.05.2007 00:18)

flickr.phillipoertel.com

just gave my flickr api toys a little overhaul. check them out. more coming soon, for example entering your username to show your contacts’ photos, instead of mine.

Posted in , ,  | no comments

Older posts: 1 2 3 ... 5