Freitag, 2. Dezember 2016

Why The Hate Against Useful UI Semantics?

Okay, this will be a rant. You have been warned.

You know, it used to be that lists were called tables, and tables had the following elements and semantics:

  • There were headers for each row with the name of the field in them.
  • You clicked on the header to activate/switch the sort to this field.
  • If the table was editable, you could tab through the fields.
  • If you left the row, you'd jump to the first field in the next row.
  • If the table had row insertion, there was an additional, empty row below the last row.
  • You added a new row just by editing this last, new row, which was marked by a little star.
  • The default sorting order was from top to bottom.
  • The scrollbar made it easy to navigate to the end of the list.
Of course, this was much too primitive. And complex. And unseemly. These days, things are way simpler and more user friendly, because the science of UX design has experienced massive improvements over the last two decades. /s

We have a hard time doing real scrolling on the web, so we reverse the sort order and perform weird "infinite scrolling" tricks so we still get some half-assed usefulness. Or we paginate the whole thing, and the user has to navigate by pushing some double-arrows. Argh.

For example, let's consider the "board" interface in pinterest:
  • Each board has a name.
  • In the "select board" popup, boards are in a vertical list, sorted by name ascending. There is no way to change that.
  • If you have more than x boards, there will be exactly three most-used boards on the top of the list.
  • There is no way to change that.
  • If you want another sort order, the only option is to somehow hack it into the name (by prefixing it with "00100" or some similarly stupid nonsense).
  • The "edit boards" interface, on the other hand, is not sorted by name, but (I guess) by creation time or id. So your whole clever hack is competely useless there. If you reorder the boards by changing their names, you get no visual feedback at all.
  • Neither is the "edit boards" interface a simple list. It's organized in tiles covering the whole screen width. You cannot change that either. I guess that one button would have cost too much screen real estate.
 Also, and I cannot stress this enough, 3D elements are evil. Because, you know, they feel like something you know from the real world, and we do not want people to have an intuitive handle on our precious UI. Duh.

Freitag, 11. Dezember 2015

Note to self:: Don't use SimpleXmlElement if you have to change the XML's contents.

In PHP, if you really HAVE to do php - never ever EVER succumb to temptation and use a SimpleXMLElement for CHANGING the XML.

It seems to have methods for doing so, but believe me, they just don't work.

You'll end up doing crazy stuff like this:

         $xml2 = self::sortArticlesByFileNames($xml);
         $xml = simplexml_load_string($xml2->asXML());

And then, of course, you have to return $xml, so if you are already returning something else, you'll end up with

        list($xml, $whatever) = doStuff($xml);

for every single function that will change the xml.

Blargh.

In fact, probably, it's better to simply refuse to use SimpleXmlElement at all. It stinks.

Just. Don't. Do it.

You have been warned.

Mittwoch, 30. September 2015

PHP and SFTP issues

We implemented an SFTP module for some website in PHP.

It was decided to use the php ssh2_* functions (PECL ssh2).

This worked as expected on the dev machines. It also worked from the staging machine towards my private external host.

The one thing that didn't work was connecting to the customer's host. Or, rather, it seemed to connect, but no file was ever uploaded. This made us all a tad sad, and me as the coder-in-charge slightly panicky.

We then proceded to install Net::SFTP (http://sourceforge.net/projects/phpseclib/). This worked like a charm.

I haven't found anything related to this issue on the whole wide internets.

What gives?

Sonntag, 12. April 2015

My vim/gvim setup for a node.js project

In my .vimrc, there is a function ProjectLoad() which will look for and read a session file in the current working dir, and then look for/source a  local .vimrc.

In the .vimrc for my current node.js project, there is a function NodeTest() which will run my project's test suite and paste the results into a new buffer.

Here are the relevant function definitions:

~/.vimrc:

function! ProjectLoad()
    if filereadable(".vimsession")
        so .vimsession
    endif
    if filereadable(".vimrc")
        so .vimrc
    endif
endfunction
function! ProjectSave()
    mks! .vimsession
endfunction

command! ProjectLoad call ProjectLoad()
command! ProjectSave call ProjectSave()

/path/to/project/.vimrc:

function! NodeIntoFile()
    redir! > out.log
    set nomore
    !node js/test/runTests.js 2>&1
    redir END
endfunction

function! NodeIntoBuffer()
    new
    r !node js/test/runTests.js
endfunction 
command! NodeTest call NodeIntoBuffer()


I wrote NodeIntoFile() while I was trying to auto-run the tests upon :w (i.e., FileWritePost), but that doesn't work out on Windows because it will always pop up a cmd window which stinks. If you know a way around that, please let me know!

Otherwise, maybe you can use those functions in your own setup.

Mittwoch, 25. März 2015

Do Your Weekend Projects!

There is a joke among me and my friends that every programmer should try their skill with the following at least once in their life:


  • a parser / parser-generator / programming language
  • an MVC framework
  • a text editor and/or a word processor
  • a raytracer
  • and just because it's a fetish of mine: a genetic algorithm
Last weekend, I was meddling around with Node.js, just to explore new territories, and I inadvertently treaded on the territory of MVC. And suddenly, a truism hit home that I had read a few times before but never quite grokked before:

You do not do a weekend project in order to get anything done.

An MVC, just as all the other examples above, has been done a trillion times, and most probably there are already thousands of excellent frameworks out there. I couldn't create something that's actually better than that. So why bother?


You do a weekend project because you will learn something, and because it's fun.

(If you're a professional coder, I sincerely hope that those two areas overlap for you. Otherwise you might consider switching jobs.)


I guess I had always had productivity and success somewhere in the back of my mind. "It isn't good if it doesn't sell", or at the very least if it doesn't solve some real-world problem.

Not true. I have fond memories of the time when programming was fundamentally fun and games and geek pride galore. Time to let go a little of the professional cynicism acquired in years of professional coding. Sure, at the job you have to, well, get the job done, and that's your top priority. But in your spare time, a little idealism can help you improve as a coder. I understand MVC better now, I have a little more insight into the nature of dynamically typed languages and DSLs, and I can happily put Node.js into my CV. What's not to love?

So, folks, have your weekend projects, hack away with pride, and DFTA!

Mittwoch, 28. Januar 2015

Using VIM as a Frontend for MySQL

Being deeply dissatisfied with MySQL Workbench, which tends to go nonresponsive on me at least once per day, I started looking around for other solutions. Since I'm a VIM aficionado, this occurred to me as one of the places to look. Of course, I got lucky.

Here's the solution (It's a slightly modified version of the code found here: http://superuser.com/questions/266934/how-to-pass-vim-buffer-contents-through-shell-command-and-capture-the-output-to):

function! FilterToNewWindow(script)
    let TempFile = tempname()
    let SaveModified = &modified
    exe 'w ' . TempFile
    let &modified = SaveModified
    exe 'split ' . TempFile
    exe '.! ' . a:script
    exe 'setlocal buftype=nofile'
    exe 'setlocal bufhidden=hide'
    exe 'setlocal noswapfile'
    exe 'setlocal noet'
    exe 'setlocal ts=25'
    exe 'setlocal number'
endfunction
command! MF call FilterToNewWindow('mysql --defaults-file=/etc/mysql/debian.cnf -t <DATABASENAME>')

Paste the above code into your .vimrc, open a new vim, and...:

  • Enter a SQL command into current buffer
  • Do :MF at the line you wish to use in mysql
  • A new buffer will open up with the results of your query. (Actually, of course, it's the other way around, but who cares...)
  • This buffer will be a scratch buffer, so you don't get an ugly error message when doing :q
You should use the mysql defaults file, otherwise your mysql credentials will end up in (I guess) your bash history. The -t argument will make mysql export its results in the nice table format used in the mysql command line client. setlocal number, noet and ts (tabsize) are not necessary, but I want them in my scratch buffer anyway.

Of course, you can use FilterToNewWindow() with all kinds of external programs. I'm sure I will put it to good use in the future.





Donnerstag, 12. Juni 2014

Tears in the Rain

<?php
class X {
    public function foo() {
        echo "foo";
    }
}
function foo() {
    echo "global foo";
}
X:foo();

This will happily print "global foo" on your screen. No complaints by the parser (nor by NetBeans or PHPStorm...)

In case you're wondering why this is strange, take a look at the T_ACHAT_NEKUDA between X and foo().

Yay.