Sun, Jan 29, 2012
![[Icon]](rsc/img/chain_link.gif)
A strength of open-source software is how customisable it is. This is a good thing. However, it has one downside - once you get used to having certain behaviour in place, it drives you nuts to be on another system that has different behaviour.
Of course, you can solve this by copying config files around. But this gets tedious when done by hand if you regularly add new behaviours. My .vimrc and .bashrc in particular change often as I learn more and come up with new features.
What you want is some way of keeping files in sync across many machines. In the old days, you'd have used something like rsync. But personally, I'm a big fan of Git.
So since I've got access to a virtual server these days that I'm not doing much else with yet, and I'm tired of having my settings not being unified, I sat down and set something up. And here's what I did:
On the server, create a repo you can drop the files into:
mkdir personal_files.git cd !$ git init --bare
On the machine(s) you want these files on, create a repo to hold the files:
mkdir gsync cd !$ git init
Now, grab the config files you want to share across systems. There's a few ways you can do this. Let's say you want to share your Bash, Screen, and Vim settings. In your ~/.screenrc add the line:
source $HOME/gsync/screen
In your ~/.bashrc add the following:
if [ -f ~/gsync/bash ]; then
. ~/gsync/bash
fi
And for your ~/.vimrc move the entire file into your gsync directory, rename it to remove the leading '.' and then:
ln -s ~/gsync/vimrc ~/.vimrc
Job done, all your files are now living in your gsync but used by your home directory. Now it's simple to go into your gsync directory, and get the files into your remote repo:
git add . git commit git remote add origin ssh://server/home/git/repositories/personal_files.git vi .git/config
You can probably do this via a git config command, but this is faster for me: Add
[branch "master"]
remote = origin
merge = refs/heads/master
..to the bottom of the file. And then,
git push
That gets all of your files uploaded to the repo. You can now create as many repositories on as many other machines as you like, have them all pull from your remote server, and you're never more than a quick git pull away from your latest config options.
Oh, and for when you've updated your Bash settings and don't want to have to log out & log back in to get them to take effect, one alias you might like to add to your shared bash file is:
alias rebash='source ~/gsync/bash
I'm hoping this little setup will make my life a lot easier in future..
Mon, Jan 23, 2012
![[Icon]](rsc/img/chain_link.gif)
At work, we frequently refer to yaks.
It's a term we picked up from the Perl community. I imagine it's used by other hacker communities as well, but I wouldn't know.
The story goes:
You wake up one morning and think to yourself, "I should mow the lawn this morning!"
Then you realise that you can't, because you don't have a mower: You lent it to your neighbour.
You figure you'll go and get it back from your neighbour, but then remember that you borrowed the neighbour's air compressor at the same time. You'll need to return the compressor if you want to get back your mower.
But the reason you haven't returned the compressor is that the hose ruptured whilst you were using it and you need to fix it before you can return it.
So you'll have to go to a hardware store to get a new hose. But you don't have a car, so you'd need somebody to give you a lift.
Your other neighbour would normally be willing to give you a lift, but he lent you a garden chair a while ago and he'd want that back before he did anything for you. And you haven't returned the chair because the cushion in it ripped and some of the stuffing came out.
So you need to fix the chair first. The chair is stuffed with yak hair. As luck would have it, you have a friend working at the local zoo, which is within walking distance. So you nip down to the zoo, have a word with your friend, and then head off into the yak enclosure.
An hour after you woke up and decided to mow the lawn, and you're at the zoo, shaving a yak. To a casual onlooker, a completely unrelated task; yet at the same time a vital prerequisite.
In programming circles, if somebody says they're shaving a yak, it means they're doing something that's vital if they want to get their main task done, but which doesn't actually get them anywhere towards accomplishing their task. In the same way that shaving a yak doesn't get the lawn mown.
Lately, it seems like a relatively simple goal has been encountering, not so much a succession of yaks, but an entire herd of them.
Here's the problem: Linux doesn't have a single GUI. It has a lot of them. From the simple & lightweight "window managers" to the heavy-hitting windows-like "desktop environments".
The one I've used for many years has been showing its age lately, and with the announcement being made that it was going into maintainence mode, I figured it was probably time to find something new.
Problem is.. I have a very specific setup. The functionality that I want is not the default for anything out there. And part of the reason I stuck with FVWM2 for so long is that nothing else is actually capable of doing what I want.
But I was confident that I could overcome that if I stuck with it. So I started shopping around for a good configurable, light-weight desktop.
Enlightenment is very shiny, but it's not nearly EWMH-compatible enough: A script I use to toggle a window between monitors doesn't work, for example.
I'm currently trying Openbox, but this has two big problems: When I toggle the mouse between monitors, the window it moves to only gets focus about half the time - this intermittent behaviour is infuriating; and there's no detectable way of enabling "warp to window" so when you use alt-tab to switch to a window, your mouse doesn't get moved to that window. Which is stupid. It means, for instance, that if I alt-tab to Firefox, I can't then use my scroll wheel because the mouse pointer is still over an xterm.
Fluxbox has possibilities, but also problems - its menus don't seem to work just by typing a letter, you have to press "return" to make something happen. This is annoying. And there's a weird bug going on where every time I toggle a window between monitors, it resizes it.
In my bid to get all the functionality that I need, I've gone from having a couple of shell scripts to having a rather large Perl program which is gaining more & more features as I try & get everything working the way I want.
It's actually reached the point where somebody at work mentioned that the X11 books by O'Reilly actually contain enough code that you can write your own bare-bones Window manager, and I'm seriously considering it on the grounds that if no other WM will do what I want, maybe my only choice is to roll my own.
But I'm going to have a go at creating a simple Tcl/Tk interface that'll call everything I need via Perl first. Because obviously, that's far easier.
Sigh.
Yaks! Yaks everywhere!!
Tue, Jan 17, 2012
![[Icon]](rsc/img/chain_link.gif)
It's the Information Age. It's easier to communicate now than it ever has been before, via a plethora of different ways.
This is generally a good thing. There are bills being mooted in the USA at the moment that would damage people's ability to communicate via the Internet, and this is why you may have seen the blackout notices on Wikipedia today - the "Nuclear Option" that made tech news a while ago where Google, Wikipedia, Facebook, etc. talked about taking themselves offline in protest. Communication matters.
But it does have its downsides. There are times when you might find yourself regretting that people can follow so much of what you say & do.
For instance, I recently got an email from someone I used to know. Completely unexpected, hadn't talked to them in ages. But suddenly, here was a message from them. Yelling at me for something I had written, which they disagreed with.
Slightly puzzled, I checked the article in question, and it didn't say what they claimed it did. In fact, it had a paragraph devoted specifically to pointing out the reasons why it didn't say what they claimed.
So I sent back a "Sorry you're upset, but it doesn't say that" reply. Rather than accept the correction, they sent a reply that shouted at me a bit more. There was a brief argument, that ended after they sent a "Not talking to you any more" reply.
But human nature can be so distressingly predictable, and I just *knew* that they wouldn't be happy leaving it there. So I gave it a few days, and then took a look at the blog published by my unhappy correspondent. Sure enough, there was a long post about not just our recent exchange, but a whole lot more too.
It was quite a post. It read like an account of the Angel of Reasonableness describing its encounter with a bad-tempered ogre. And obviously, when two people give an account of something, you expect discrepancies - different perspectives, different recollections, and the inevitable personal bias.
But the more I read, the more cynical I became. It went from "harsh" to "unfair" to "near absurd" before I finally came across one point that just couldn't be explained away by subjectivity or hindsight: An accusation that I had said/written something that I knew I hadn't. Just to be sure, I went back to my sent messages and checked. Nope: Clear as day, with no possibility that it could be misread or misinterpreted. I had absolutely, definitely, said the exact opposite of what they claimed I had. This wasn't a faulty recollection or an impassioned over-statement. It was a flat-out lie.
With that in mind, I re-read the post with my cynicism turned up from "They might be exaggerating" to "I know they're lying" and re-interpreted it on that basis. My final conclusion?
It was bullshit.
That pretty much sums it up. It re-writes history in a deliberate attempt to make it look as bad as possible. It over-states, it distorts, and in several places it just outright lies. Even with every possible allowance made, it's not possible to believe that the author actually believed what they wrote. Not without casting grave doubts over their sanity, anyway.
I debated replying, maybe with some screenshots of the various messages/articles/etc. that contradict their account plainly highlighted. But I decided against it - communication is a wonderful thing, but there's such a thing as too much of it. I'd already clearly pointed out discrepancies between what I was accused of and what I had actually said in the earlier argument, all of which were brushed aside & ignored. What would it accomplish to point out yet more?
So I dropped it. They can carry on happy to have got the last word; I can carry on happy that I don't really care.
Funny thing is, if this had happened a while ago - as little as a year ago - it would have bothered me massively. Somebody who I used to be quite close to, saying and thinking such nasty things.. It would have nagged at me all day and kept me awake at night. Maybe that was their intention.
But the last few years have had a lot happen in them, and it appears they've changed me even more than I'd been aware of. If someone wants to rewrite their past to justify being unhappy in the present, they're welcome to. I gave up on being this guy years ago:

Fri, Dec 30, 2011
![[Icon]](rsc/img/chain_link.gif)
The previous JS example was all well & good - it used a closure to store the data it needed - but it was a 'public' variable - you could intrude on the object and change the value yourself. This is bad, of course.
THIS is far better: Instead of creating a function object, you have the function create and return a new object, which has access to the lexical scope of the function that created the variable.
Nothing else can access that scope, so you now have a nice private variable. This same approach can give you private data, private methods.. it lays the groundwork for entire encapsulated modules, without having any cluttering of namespaces or use of global variables.
In fact, it's almost like using a slightly old and crippled version of Perl. It's that good.
Try it yourself in your browser's console: Paste the code below in. You can still run count_hundred.count() to increment the value, and I've added the .get() method as well, to return the count without incrementing it. But ONLY by using these methods can you get the value: The data is protected from tampering by its scope.
This is something I just didn't think you could do with JS. I'm almost starting to like it.
var counter = function (start){
start = typeof start == 'number' ? start : 0;
return {
count: function() { return ++start;},
get: function() { return start;}
}
};
var count_hundred = counter(100); Wed, Dec 28, 2011
![[Icon]](rsc/img/chain_link.gif)
I hate Javascript.
Mostly because of things that aren't really its fault, to be fair:
But when you look under the hood.. it's no better! Global variables, weird scoping (A helper function defined inside a method gets the global object bound to 'this' instead of the object bound to the method's 'this', FFS), godawful class syntax...
So when somebody at work recommended a book called "JavaScript: The Good Parts" my immediate reaction was "It must be a very short book! Ha! Ha!"
It is.
150 pages, and 50 of it's appendices. Only 100 pages could be written about what's good about JS.
The blurb on the back of the book? Well, it begins:
Most programming languages contain good and bad parts, but JavaScript has more than its share of the bad
This seemed promising.
And it is. It's a damn good book. It throws out all the cruft and the useless "Hello, world" nonsense that most JS books blither on about, and just tells you about what JS got right and how to use it properly.
Don't use the class syntax. JS isn't classical: It's prototypal. An object isn't an instance of a class; you make a new object by linking to the prototype of the type of object you want.
Don't think of it as anything to do with Java, don't think of it with your C hat on. It's more functional than procedural: Put your Lisp/Haskell/Higher Order Perl hat on. Don't think about global variables, think about data stored in closures.
And suddenly if you want, say, iterator objects, you don't have a bunch of global variables or bad class syntax. You can dump all of that and create objects with closures that you can pass around by reference. And it's almost like you're using a decent language again!
var Counter = function (start){
this.counter = typeof start == 'number' ? start : 0;
};
Counter.prototype.count = function (){
return this.counter++;
};
var count_zero = new Counter();
var count_hundred = new Counter(100);
var count_badly = new Counter('wibble');
As simple as that, you can now get the output:
- count_zero.count(); 0 - count_zero.count(); 1 - count_hundred.count(); 100 - count_hundred.count(); 101 - count_badly.count(); 0 - count_badly.count(); 1
All nice and sane. And, compared to what you usually see in JS, quite elegant.
If the rest of the book is as helpful as the first third, I live in hope that I may yet be able to add "Just use raw JS" to the existing list of "Use Jquery" and "Learn EXT" that I currently have available for making web pages dynamic.
:: Next >>
![[Links]](http://geekblog.oneandoneis2.org/skins/112/rsc/img/chain_link.gif)
Facebook Syndication Error
03/02/12
![]()
I last listened to:
Johann Pachelbel - Canon in D major
Most recent photo:
Submersible houseboat