Tuesday, 30 August 2011

Link: training self-discipline

As a telecommuter, I well know the struggle with self-discipline. It's very hard to keep away from all the regular home-distractions and actually get down to work. But it's a necessary part of every day life.

This article on training self-discipline has some good tips on how the author has been working towards better self-discipline, and also some good general discussion on the benefits.

I especially agree with his point that you need much more discipline if you have large amounts of freedom. I remember it being much easier to get down to work when I had to actually get up and go into the office at a set time each day.

Anybody else here telecommute? Do you do anything to wok on your own self-discipline?

Thursday, 25 August 2011

Emerald isle and censorship link

Hi all - sorry I've been quiet... I've been away on holidays in Ireland, learning how to pour the perfect pint of Guinness :)

There's several comments I need to reply-to, but my schedule's all haywire due to the holiday and my birthday plans... I'll get to you eventually I promise!

In the meantime, gizmag have posted an article abut an plan to let people in heavily censored cultures (eg China) get past the censorship with an interesting protocol called Telex that hides requests in the HTTP headers of normal, uncensored web requests. Kind of an interesting idea. Enjoy

Monday, 15 August 2011

Life at 36

When I was 5 I liked to do jigsaw puzzles upside down (to make it harder) and blow bubbles off the balcony -- watching them drift over the street. I liked to walk to school by myself (one block) and learn Origami from the lady in the flats behind us.

When I was 7 I wished on every star that I could have a baby sister. When I was 8, I got one.

When I was 10 I liked to explore the backways of Oyster Bay, picking flowers to make perfume (which smelled terrible). I played fantasy make-believe games with my cousins - involving magic and unicorns, where we saved the world.

When I was 12 I got another sister.... I stopped wishing. :)

When I was 13 I liked to play make-believe with my sisters and all the younger cousins. Gordy and I plotted adventures for us all, in-amongst the bamboo.

When I was 15 I like to climb up on the roof and watch the clouds drift by. I liked to ride my bike home from school and play LARP in the park across the road.

When I was 17 I liked to swim in the backyard pool, drifting underwater with my hair floating loose around me. I liked to frantically scribble in my diary and day-dream about movies; making up adventure stories or inserting myself as a character in my favourites.

When I was 20 I loved the freedom of being independent, waking up in my own flat to the sound of Cockatoos in the pine-trees. I liked being free to wake up in the afternoon and go for a walk in the twilight, or in the quiet time after the curfew painted the streets with night. I liked staying up all night, having coffee with friends, as television got progressively more idiotic. As the sky began to warm with first light - I went out again. I liked feeling the expectant hush of the cool dawn, then retiring before the hustle woke up.

When I was 22 I loved my writing diary - pouring out my heart or playing with words, crafting new worlds on a page. I liked learning new things -- drifting from subject to subject. I liked psychology, programming and the occult. I loved my cats. I liked it that I got married and was somebody's wife. I liked meditating with my husband -- humming toneful chords without meaning. I liked learning martial arts with him.

When I was 24 I loved my garden. I spent days drifting through it and tending to the plants. I liked picking silver-beet and herbs and cooking up a meal that I'd taken from seed to table. I liked shopping at Bunnings for fruit trees. I liked spending Saturday nights with the Druids, singing, meditating, drinking mead and telling stories. Then the morning-afters, skinny-dipping in the wading-pool as the sun climbed the sky.

When I was 26 I moved interstate by myself, to see the Big City. I liked exploring the back-areas of Chatswood in search of great food. I loved hacking together brilliant solutions for colleagues desperately late on their projects. I liked rock-climbing with my work-mates and playing network games in the training room until late at night.

When I was 28 I loved freedom. The freedom to choose my own time, to choose what to learn, to work on my own projects. I liked smiling at my young class-mates who complained about the work - knowing this was easy compared with Real Work. I liked the meditation of archery. I liked spending my time reading while sipping coffee, or eating noodles at the local hole-in-the-wall. I liked long walks in the evening, scoping out my local territory.

When I was 30 I liked building my own small business, knowing I owned it and I could achieve whatever I wanted. I liked learning medieval crafts alongside eager students, and feasting with friends in a medieval campsite. I liked reading books, sipping coffee after a good workout at the gym. I liked watching myself learn how to walk again.

When I was 32 I enjoyed being a senior developer, being at the top of my form as well as earning high pay. I enjoyed choosing my first major investments in shares and buying my first property. I loved planning what to do with my life, and choosing to gather interesting experiences around me - New Zealand, the Northern Territory, Thailand. I learned photography, spanish and investing. I watched a *lot* of DVDs.

When I was 34 I moved internationally by myself. I loved exploring in a new country: visiting ancient ruins and watching Shakespeare at the Globe. I enjoyed getting better at photography, meeting new people and seeing new places. I built my own startup with friends. I enjoyed my morning coffee at the local in Windsor, and walking past a castle on my way to work in the morning. I loved pottering around in my allotment late into the long, english summer nights.

When I was 36 I loved getting about europe in my first car; learning French, and then eating my way around the French countryside. I enjoyed picking fresh fruit/veg from my allotment and making blackberry pie. I loved the lazy schedule allowed by working from home, and lazy Sunday afternoons drinking velvety latte with a Cranberry-and-orange muffin at my local cafe in Windsor, in view of the castle.


This post began as an exercise: "for every five years, write what you enjoyed doing". It helps you find out what you most enjoy - and how your tastes change over time. I also like to do it to remind me of the good things in life - which can be so easy to forget sometimes.

Friday, 5 August 2011

Crocker's rules

Declaring yourself to be operating by "Crocker's Rules" means that other people are allowed to optimize their messages for information, not for being nice to you.

I love it.

I now declare that I operate under Crocker's rules. Call me out on my bullshit - I want to know the real truth. Especially call me out (and remind me of this post) if you see me having a problem operating under Crocker's rules themselves.

I think I have been subconsciously operating under these rules for quite some time now. Admittedly - I also use them (a lot) on other people... even if they haven't asked for it. It is debatable whether this is a Good Idea.

I still find it a much easier atmosphere to work in - if you don't have to go through backflips of pleasantries just to say something without accidentally insulting the other person: not because what you're saying is insulting - but because you failed to put in the correct, socially-acceptable amount of padding...

Compare:

"hi there, how are you, hope your holiday went well. By the way, you know a few weeks back you borrowed my stapler. I was wondering - if you have finished with using it, that you might possibly find some time to bring it back? If that's ok. thanks a whole bunch.. love to the kids - T"

vs

"hi, could I please have my stapler back? T"

The full set of Crocker's rules here

How about you? Do you dare take the challenge? Disagree with the whole concept?

Friday, 29 July 2011

Link: Computer Stupidities

I've just come across: Computer Stupidities. Its a lot of fun. I think my favourite so far is:

When I was studying programming, one of my classmates was having serious troubles with his program. When he asked me for help, I leaned over his screen and saw all of his code in comments. The reason: "Well, it compiles much faster that way."

Much like Daily WTF... though most of the CS stories are very early era

Warning! Time sink!

Sunday, 24 July 2011

Who Cares About Forecast Accuracy?

Corporations and governments spend staggering amounts of money on forecasting, and one might think they would be keenly interested in determining the worth of their purchases and ensuring they are the very best available. But most aren’t. They spend little or nothing analyzing the accuracy of forecasts and not much more on research to develop and compare forecasting methods. Some even persist in using forecasts that are manifestly unreliable. … This widespread lack of curiosity … is a phenomenon worthy of investigation.

An eye-opening article by Robin Hanson, called Who Cares About Forecast Accuracy?, describes how and why corporations spend heaps of money on making predictions... but almost none on testing whether those predictions actually worked out.

The article discusses the fact that actually recording the accuracy of pie-in-the-sky forecasts means that it's much harder to hide a poor track-record for leadership. That a lot of forecasting is more about signaling affiliation to the company ("yeah, we're doing great, I predict we'll be done by tomorrow!") than actual accuracy. Quite possibly just another effect of bosses preferring overconfidence to accuracy.

From my own experience - I find that many "leaders" don't want you to say that the project might be in trouble... and the article discusses how this can happen because the middle-managers don't want somebody to go on record as having questioned their vision... because it'll reflect badly on them down the line should something go wrong. It's much harder to sweep losses under the carpet if nobody officially takes notice of how often it happens.

I think there's also another reason, not mentioned in the article. That being the long-term vs short-term payoffs. The strategic echelons of an organisation need your predictions so that they can make their own overall predictions of how long a plan will take to implement. But they don't want to bother with the long-term cost of implementing a full system with all the process-change and downtime that it will take. I've personally found it extremely difficult to "sell" both management and fellow-programmers on changing to to a methodology which will allow for recording and feedback of prediction accuracy. These are methodologies that aren't particularly heavy or difficult to implement (compared, say, with six-sigma), but which provide a quick and easy way to get better at providing an accurate estimate of your times.

The problem seems to be, that it takes more time and effort to implement, and people don't want to do the "work". They want to make their guesses *and* make t more accurate... but not to have it impact the "bottom ilne" in any way. This is a bit like saying "we'd like to buy faster computers, but won't give you any budget for their increased cost". You somehow have to just improve anyway.

What normally ends up happening is that you don't properly implement any system of accuracy, so you end up simply guessing and just hope for the best. Actually spending the effort to make those guesses meaningful is too much like hard work, and nobody wants to add to their workload. This is understandable... but not exactly helpful (or realistic). Instead of improving over time, we continually wallow in a world of wild guesstimates and "fudge-factors" that never seem to quite cover the extra time it always seems to take.

To get back to the article, Hanson suggests that we use a betting-system to literally "put your money where your mouth is"... the intention being that if you personally stand to win/lose by your prediction, then it would be in your best interest to start being more accurate.

I think I'd balk at my own actual money, but I'm sure some kind of system could be set up for "points" where you "win" various rewards (eg an extra day off, or even just the ability to work on "the fun project") if you do especially well.

Has anybody had any experience with estimates and measuring their accuracy? Either from the trenches or the strategic side of things?

Tuesday, 19 July 2011

Freedom

To me, freedom is the ability to choose my own timetable; to choose in which direction I can travel, and what level of quality to aim for. Freedom does not mean being completely unburdened (as you cannot go very far when you choose to do nothing). It is the freedom to choose which burden to carry - rather than accepting the one forced upon you.

We are all constrained to one degree or another. I'd rather choose my own constraints than to wear shackles chosen by others.

What does freedom mean to you?

Tuesday, 12 July 2011

Consulting harms your chance at founding startups?

Consulting is like selling crack. If you get hooked on the consulting lifestyle (and income), it can be hard to give that up to work on your own startups, yet many people get into consulting with the dream of working on their own projects on the side.

Yet it seems that consulting work can actually be detrimental to your startup-founding prospects. Read more from the original article

I have to admit I've fallen foul of this myself. It's very hard to prioritise spending a lot of time on a "maybe it'll go nowhere" startup, if you've got definite paid work to do right now (especially if it's well paid). In my case, my startup is MatchFounders, a site dedicated to matching potential founders for startups.

When prioritising, the "bird in the hand" mentality kicks in automatically - and there's a lot to be said about that particular proverb. But I also have to think hard about whether or not I'm selling my long-term future for short-term cash results.

It's not an easy choice to make, by any stretch.

Just how much do I want to work my own startup (and build something for the future) vs current, well-paid consulting.

Don't hold your breath for an answer - I'll probably struggle with this for a long time. But it has served as a reminder that I also have my own ideas on the boil - and should maybe give a little more love on their behalf.

What about you? Are you struggling to make the choice? Have you already made it? Do you have any advice?

Wednesday, 6 July 2011

What's your opinion?

I've recently read the Jeff Atwood's post: A blog without comments is not a blog, and realised that, while I don't have comments turned off - I don't exactly go out of my way to encourage much commenting on this blog.

I'd just like to say that I really do want to hear your opinions on the stuff I say. I'm frequently quite opinionated, and more often wrong than I like.

I may not give this impression, but I like to hear what other people say about a topic to get other points-of-view or even just to figure out my own blind-spots (by having them pointed out to me by somebody else).

So I've decided I should do what I can to encourage more frequent commenting here.

I'm not entirely sure how to go about it... but I figured I should start with a small change. From now on, I'm going to try and end each post with a question - in the hopes of sparking a conversation about what I've been talking about. Maybe it's a dumb idea - but I figured I should begin somewhere.

Does that work for you? If not, what does? Do you have other examples of good ways of getting regular comments on a blog?

Friday, 1 July 2011

How to find technical co-founders

Jason Freedman has clearly been asked one too-many times how to find technical co-founders and has written this excellent post so people will please please please stop asking how to find technical co-founders. :)

Fun to read if you are technical and, from my perspective it seems really useful if you're looking for one.

Monday, 27 June 2011

EU cookie law: in video

A while back I pointed out that a new law about cookies was coming out. Well, that passed into law in the UK on 26th May 2011.

It is now illegal to have cookies on your website without explicitly asking for permission.

That includes your google analytics tracking tags!

Luckily, they've realised what a pain it is to update your website, and have told everybody that they will not actually prosecute anybody with this law for a year... as long as they are actually doing *something* about the issue.

It also makes sense to start thinking about now, if only to make sure we're not all madly stuck trying to rectify the problem at midnight May 25th next year.

Of course the problem is that there is still no consensus on what we actually need to *do* to meet compliance. The ICO's guidance on the topic still being woefully inadequate.

There's more from the Guardian on the cookie law shambles.

and here's a great YouTube video that briefly describes the whole issue.

Monday, 20 June 2011

What the hell is happening with Rails?

A whole slew of controversy has been stirred up with the post: What the hell is happening to rails - which managed to top the hackernews charts for quite a while last week.

It basically gave vent to a lot of concern in the rails community that rails is becoming too difficult to learn, and that may be scaring off newbies.

The new rails has certainly been in a great state of flux - and pushes the whole framework in a new direction. Whether or not you like that direction is one thing - but the fact that it is such a big change makes it difficult to know where to start if you're coming into the community for the first time.

I recently had an eye-opening experience at a hack-day where I suggested rails as a platform-of-choice for us to use... then spent the entire day helping one guy just get a basic rails stack up and running on his laptop, and then I still had to explain how to actually use it.. This isn't as easy a I remember when I first began.

One of the big benefits of original plain-ole-C was that anybody could learn the entirety of the language and keep it in their head all at one time. Contrast that with any of the big enterprise languages, which require a long ramp-up time even just to learn everything that is available in the basic suites. Not that having less is better - but it does make the early-learning stages much quicker... so I can see the point being made here.

In any case - I think the gist of the post/discussion is worry over the potential dilution of the framework. If we want to be all things to all people - it means a lot of work to genericise the platform, and that means big changes.

On one hand, I can see why it's being done. There are good reasons for all of the alternatives to the core-defaults... and being able to support them therefore opens up our audience to a greater market. But I can also see the point that it makes Rails *feel* a lot more bloaty than before... even if it isn't actually degrading performance, and it gives newbies so much more to learn just to get out the starting gates.

In any case - Yehuda Katz has now done a follow-up post explaining just What’s Up With All These Changes in Rails? - and it's worth a read to see why they've made some of their recent decisions.

and I plan to watch the continuing discussion closely...

Saturday, 18 June 2011

Goal-oriented vs process-oriented motivation

There are heaps of processes that I enjoy far more than the actual end-result.

Crochet is my example.

I'm quite happy to continue crocheting something pretty (it has to be pretty - I don't enjoy crocheting abominations) for a long time and never "owning a crocheted thing" at the end.

Before I hit upon the solution, I spent a long time starting projects - some of which I finished, but lots I didn't... because I didn't care about finishing - just about doing. Of course, couple this with an aversion to destroying something I've already made (which might have solved the problem by turning it into a sisyphean task). and I got a lot of "why don't you ever finish anything?" from my mother.

The question usually comes as "why don't you ever finish anything, don't you want the [crocheted thing] you set out to create?" - and the honest answer is "no".... but if you say that - they ask "well why did you start making it in the first place?"

Most people don't seem to understand enjoying the process - at least not on a gut level...

I actually solved this particular dilemma by giving away my crocheted things to my grandma - who likes owning crocheted doilies et al. Works for embroidery projects too.

Unfortunately, I still tend to get lack of understanding from other people: "but why don't you ever make something for yourself?" I find it *very* hard to explain to goal-oriented people why I don't like crochet... I like crocheting.

I would definitely consider myself to be more process-oriented than goal-oriented. I like doing stuff... I like crocheting, not the goal of having crocheted something in particular. Especially, I like learning - not the feat of "having learned something".

So for me - it's very difficult to go to those "attain your goals" seminars etc - because I don't have set goals. I can't point at something and say I want to have achieved precisely that thing, because for me, the thing itself doesn't matter.

It can be frustrating, because I certainly do want to improve over time. I crochet better and more complicated things, I study more challenging topics that build on past learning that I enjoyed. but I can't necessarily quantify that I want to "learn X".

Because there is no X... or at least no specific X.

and then people tell me I'm drifting and that I'll "never accomplish anything"... but accomplishing specific things for me isn't the point. I enjoy the act, not necessarily the achievement.

Of course, over time, I *do* accomplish things - because if you continue to, say, crochet over a long period of time, eventually you will have piled up a very large back catalogue of doilies... and the same goes for learning or whatever other process you enjoy. Which I can then, of course, show to my mother...

who then invariably says "but why don't you finish the ones that are still in your cupboard?"

*sigh*

Friday, 10 June 2011

Project Euler

I've found a fun new site. Project Euler is a huge set of math+programming puzzles of increasing difficulty, starting out pretty easy (solved by tens of thousands of participants) and going up to puzzles that haven't been solved yet.

They're quite fun. Each one touches some aspect of mathematics, and requires some programming smarts to get it working. But don't worry if you're not cluey on maths. They start out fairly simple, and you can google for information about the math behind the puzzles if you need more.

Each puzzle has a specific, numerical answer. You submit the answer to prove you've solved the puzzle, and the site keeps track of how many you've done. It also gives you access to a forum for each puzzle - where others share their code or insights into how to make the program more efficient. Most puzzles also come with a short pdf to explain the maths behind it - generally showing you how to analyse the problem or prove the formulae behind the most efficient algorithm.

Each puzzle has been constructed so that the correct program/solution is expected to run in under a minute... and for many of the puzzles - that means you'll have to rethink how your program works to get in under that time.

Anyway, I think it's an interesting challenge to play with. Here's my score so far:

Sunday, 5 June 2011

ruby encapsulation is for $%*t

Wow, I just learned that ruby encapsulation can be broken by simply using:

   my_object.send(:my_secret_private_method)

That's kinda useful to know if you're trying to unit test a private method, but makes the concept of encapsulation totally meaningless in ruby.

Apparently, Ruby 1.9 revokes this "special" privilege, but then there are still many ways to use the power of ruby meta-programming to get to them anyway (see above link for some examples).

Wednesday, 1 June 2011

Autologin to rubyCAS after create user

From restful_authentication I first got the idea that when a user signs up they can also be automatically logged-in. This as opposed to having them register - then sending them to the login page where they have to re-enter the details they just typed into the registration-form.

Unless you have some kind of click-on-the-email-activation-code-before-logging-in requirement, you shouldn't force your user to go through this dance. It's a tiny nice-to-have that (if all goes well) ends up with a more seamless experience for the user - all win.

If one of your rails apps also deals with signing up your new users - you should be able to mirror this autologin functionality to smoothly get them started straight after registration.

At first glance, it looked like rubyCAS didn't support this - or at least not easily... but it's all tied into the same functionality as logging-in via a form. Autologin uses the same login_to_service method in your create action. You should already have the user's login credentials, so post them to the service and redirect them to whatever "getting started" page they should begin with. You can even just reuse the same cas_login action itself.

So, in the action that creates/registers a new user, add this at the end:

  def create
    # creating a new user code goes here
    if success?
       redirect(cas_login_path(:login => @user.username, :password => params[:new_password]))
    end
  end

Just don't forget to use the pre-encrypted password. :)


This is one article in a series on Rails single-sign-on with rubyCAS

Thursday, 19 May 2011

How not to invite me on LinkedIn

I'd like to add you to my professional network on LinkedIn.

- J Citizen

I hate that... I really do.

So - who the hell are you? and why should I add you to my LinkedIn? and is it really so hard to type just a few words into the text box?

If we've never met before - I don't know you from Adam. If you couldn't be bothered writing a few words about why we should link up - why should I be bothered accepting your invite?

Unsolicited invites with no effort read as SPAM to me, and will be ignored.

I find this particularly common from recruiters trying to fish for Rails developers. Yet the very people you most want to hire are the most likely to ignore a "form-letter" style invite. How many potential goldmine recruits are ignoring you because you didn't put in the effort to explain who the hell you are?

Or maybe I have met you - do you know how common some names are? Like most geeks I'm *crap* at names and I apologise, I've probably forgotten yours... it's nothing personal - but I've met thousands of people in the past year.

You and I probably hit it off at some networking event and we had a great conversation about your new startup and how we could work together... but that doesn't mean I remembered your *name*, it means I remembered who you *are*. Unfortunately, LinkedIn invites only show a name... so you'll have to remind me of who you are... it only takes a few words:

Hi, I'm John, we spoke at Launch48 last year about my new startup FuzzyKittens.com. 
I'm looking for an awesome Rails developer to help on my project. 
Add me to our network?

- J Citizen

*so* not hard.

Wednesday, 11 May 2011

Travel Hacking Cartel

I've been doing a *lot* of travel the last couple of years: taking advantage of my stay in the UK to see as much of Europe as I can before I have to head home to Aus.

Mostly I've been traveling on cheap airlines or even driving. However, I've just joined a website that helps you collect airmiles at a much increased rate. They guarantee that you'll gather a minimum of 100,000 airmiles a year (even if you aren't based in the USA) which adds up to at least one significant trip each year.

They find the deals for you and list them on the member homepage, and you then go and collect your points and mark them "done". The claim being that you only need to spend half an hour each month gathering your points. Seems fairly good so far, but I'll let you know as I go along if I think it's worth it.

If you're interested, click on the linked image below.

Official travel hacker

Friday, 6 May 2011

admin_login_required filter for rubyCAS

Setting up an admin-only login for rubyCAS is fairly straightforward.

First, you have to add an "is_admin" boolean flag to your *local* user class. Remember that you will probably want to restrict admin-rights differently on different applications - so it's better to put it in the local db for this.

If you are really sure that you want universal admins - then you can look into using the "extra attributes" aspects of rubyCAS - but I won't cover this here today.

Now it's just a matter of adding this helper-method to application_controller.rb (note, this depends on logged_in? and current_user)

    # overload the restful_auth version
    def admin_login_required
      # send them to 404 so we don't leak the page's existence
      # Note: implementation of this method left as exercise for the reader...
      render_four_oh_four and return(false) unless logged_in? && @current_user.is_admin?
      true
    end

Now you can add this as a before_filter to whatever actions you need... but make sure it comes *after* the actual login filters eg:

  class MyController < ApplicationController
    # this is the before_filter provided by rubyCAS client
    before_filter CASClient::Frameworks::Rails::Filter
    # this is a call to our own new before_filter which populates the cas user
    before_filter :setup_cas_user

    before_filter :admin_login_required, :only => :admin_homepage

  
    # actions here
    def admin_homepage
      # load cool admin-only stuff here...
    end
  end

To actually update that flag - you'll need to have local versions of user CRUD pages as per any other CRUD pages - affecting the local user values.

This is one article in a series on Rails single-sign-on with rubyCAS

Thursday, 28 April 2011

Gateway filtering in RubyCAS

Gateway login pages are ones where a user doesn't need to be logged-in... but if they already *are* logged in, then we want to know. Example: the help or contact-us pages are available to non-logged-in users.

Often we want to write these pages using the existing templates so that if they aren't logged in, the templates are fairly simple, but if they *are* logged in, then you display the usual logged-in navigation links.

So you need a filter that will auto-authenticate a user *if* they are already logged in, but doesn't *require* it. The standard CAS-login filters will actually redirect non-logged in users to the login page - and we don't want that happening. So we need to write a little filter-magick using the CAS GatewayFilter.

class WelcomeController < ApplicationController
  # don't *require* login for the public pages (inc actual login page)
  skip_before_filter CASClient::Frameworks::Rails::Filter, :only => [:home, :contact_us, :terms, :cas_login]
  # instead use gateway-login filter
  before_filter :cas_gateway_login, :only => [:home, :contact_us, :terms, :cas_login]

  # ... lots of actions and stuff here

  #####################################################################################
  private
    
    # This before_filter method is used to both call the GatewayFilter and
    # also to then call the setup_cas_user method.  Note that the latter
    # will already have been called on an action, but as we declare the
    # GatewayFilter *after* this, it must be declared again.  So we use this
    # method to make sure that we do both of these in the requisite
    # before_filter.
    def cas_gateway_login
      return false unless CASClient::Frameworks::Rails::GatewayFilter
      setup_cas_user # setup @cas_current_user etc for use by other methods
    end
end # controller

After this, you can use the logged_in? method to determine whether or not to display extra navigation features.

This is one article in a series on Rails single-sign-on with rubyCAS

Saturday, 23 April 2011

Gotcha: NoMethodError: undefined method RuntimeError

So... I wrote some code in a plain-ruby class that raised a RuntimeError somewhat like below:

    class MyClass
      def initialize(opts = {})
         # do stuff
         thing = opts[:thing]
         raise RuntimeError "must have a thing!" unless thing.present? && thing.is_a?(Thing)
         # more stuff
      end
    end

and when I ran my fresh new rspec spec over it -> which looks somewhat like:

    it "should raise an error if we don't pass a thing" do
      lambda {
        my_class = MyClass.new(:thing => nil)
      }.should raise_exception(RuntimeError)
    end

I kept getting something weird:

    expected RuntimeError, got 
    #<NoMethodError: undefined method `RuntimeError' for #<MyClass:0xb5acbf9c>>

You may already have spotted the problem... ah, single-character bugs, doncha love em?

Here it is.

WRONG:

     raise RuntimeError "must have a thing!" unless thing.present? && thing.is_a?(Thing)

RIGHT:

     raise RuntimeError, "must have a thing!" unless thing.present? && thing.is_a?(Thing)

of course, you can also just go ahead and leave out the RuntimeError entirely:

     raise "must have a thing!" unless thing.present? && thing.is_a?(Thing)

because it's the default anyways... which makes it nice and defaultish for you.

Tuesday, 19 April 2011

RubyCAS - logged_in?

A logged_in? method is fairly common in rails authentication these days. We use it to determine if there *is* a logged-in user for layouts that are shared public and private - for example to use for greetings, login-only navigation features and displaying the correct login/logout buttons.

Once you've implemented CAS signup and a current_user method, you can use the very simple code below on your ApplicationHelper to get the logged_in? functionality

  def logged_in?
    @current_user.present?
  end

Some authentication applications (eg restful_auth) will use a call to logged_in? as an opportunity to actually try to log a user in... but RubyCAS is more complicated than a simple cookie-login... so I've left actual authentication just to the filter-mechanisms already described.

If you have templates where - if you *can* login a user, you'd like to... but you'd like them also to be available to non-logged in users, then you'll need a Gateway filter.

This is one article in a series on Rails single-sign-on with rubyCAS

Thursday, 14 April 2011

If a bricks-and-mortar shop were run like a web-deploy

"Hello, emergency response unit, what is your emergency please?"

"Yes, hello, I'm glad I *finally* got you... you have to do something immediately, it's an emergency"

"Yes sir, please tell me what is the nature of your emergency"

"Welll you see, I was in the middle of taking a customer's order, and they were trying to pay me the money, but then the till drawer got stuck and..."

"I'm sorry, sir, did you say the *till* got stuck?"

"Yes, that's right! The drawer got stuck and wouldn't open, and of course, you know, that means I can't take orders... so I called you and you have to fix it."

"I'm sorry sir, we don't really deal with this level of problem - perhaps if you called your building manager during normal work hours..."

"You fix things that are broken, yes? so fix it!"

"Yes, but you've called the emergency support line, not the..."

"What? I pay for this support service, I know you can fix it... just get it working, it's losing me business!"

" have you tried ringing up the sale first?"

...silence...

*taptaptap* *kerCHING!*

"Oh"

*click*

...later that day... after the building manager arrives

"No, no, I'm sorry but you're just going to have to destroy the entire store and start over.."

"I really don't think that's necessary, it's just a few design issues that we need to sort out..."

"Just a few design issues! This is a total branding failure. The display at the far right of the store isn't showing the products we asked for, this will completely ruin our business!"

"But... you're the ones that are supposed to set those products - we just filled it with some cardboard-cutouts so you'd get the idea of how to use it"

"I don't care - it's not what I expected! I expected it to work properly and it doesn't... I swear, I've been looking at sales, and they aren't as high as they should be and so it *must* be this display putting them off. There's nothing else that will do, you just have to destroy the new store and rebuild the old store for us!"

"What? We can't do that at this stage! Do you know how much work it'd be to tear down this new building and rebuild the old again? Are you going to pay for it?"

"Why should *I* pay for it? You messed up the display!"

Another day...

"That's it, close the doors, no customers are allowed in!"

"What's going on? why are you closing up?"

"It's a disaster! You see this picture here? it should be over there! and it's hanging askew!"

"Askew? I don't see it."

"Look at the other two pictures here... they line up with the edges of the cashier's desks exactly... but this one? Do you see why it's so wrong?"

*looks*

*looks some more... *

"I'm... really sorry, but I just don't se..."

"I don't believe it. See, does this help?"

*holding up a ruler*... "the third picture is *1cm* over the edge of the desk"

"Oh, I see it now. Yes - we should straighten that up for the next store-refit"

"Next refit!" *shocked look* "It's a disaster! We can't wait until the next refit! It's terribly unprofessional!"

"...but it's scheduled for tomorrow night, and it's not like it's impacting your cashflow..."

"not impacting... !!! ... It's *ruining* our brand-position! How could you have let something like this go out the door! Can't you get *anything* right? the entire design is ruined!!!"

*stunned look*

"OMG! *that's* we we aren't taking any orders, it's all your fault! we're losing business because of this! fix it now!"

...

Tuesday, 29 March 2011

Designing serious games - a request for help

I've been hanging out a lot on Less Wrong, which is a community for people trying learn about being more rational.

Some of us are also programmers... so we've decided to get together and have a hackday (in London). But we're still trying to figure out what would be both cool/interesting *and* help us build our rationality, *and* still be doable by an odd collection of random hackers over a single day.

One idea would be to have a go at designing serious games - games specifically created for improving our rationality, a bit like Lumosity builds games for improving mental agility.

But we need help coming up with ideas. Ideas that are not only small enough to fit into the time-schedule of a hackday... but that also demonstrably improve some aspect of our rationality.

If you have any ideas (or would be able to comment on those we've got), come over to our site and add our comments to the Designing serious games discussion.

Thanks

Saturday, 26 March 2011

Link: UX lessons from Angry Birds

Angry Birds is one of the most successful games out there right now - consuming millions of hours worldwide every day. What have they got right? This article tears down the user experience and explains Why Angry Birds is so successful and popular. It's a thorough and thought-provoking look into the sorts of things that make up a truly engaging user experience.

Wednesday, 23 March 2011

How to learn about everything

In How to understand everything and why, Eric Drexler (author of Engines of Creation), explains the importance of a broad education simply:

"It’s important... because it makes creative work more productive and makes costly blunders less likely... "To avoid blunders and absurdities, to recognize cross-disciplinary opportunities, and to make sense of new ideas, requires knowledge of at least the outlines of every field that might be relevant to the topics of interest."

he then follows with a brief discussion of how to go about learning everything - a method that seems straightforward, and even fun. Worth a read.

Thursday, 17 March 2011

Link: Assuming goodwill

Seth Godin's blog is packed full of great insights, but I thought I'd outline a recent one.

Assuming Goodwill is about the decision to trust, because trust pays.

It's one of those common-sense things that we often forget, that people will live up to your expectations. Expect the worst and that's what you'll get, but expect great things and you'll get the best. Seth talks about trust as it relates to, say, a restaurant trusting you to pay *after* you've eaten your meal... or Tiffany's trusting you to try on their expensive jewels... but obviously this has application to the full breadth of life.

For example, an employer trusting their employees to be productive and loyal builds an environment that is more conducive to productivity and loyalty, than one who micromanages productivity, or constructs labyrinthine rules about allowed corporate protocol.

Yep, sometimes your trust will be abused... life is like that. But sometimes you have to risk a little, to gain a lot.

Friday, 11 March 2011

Heads-up: new EU cookie laws

The laws are changing around cookies. From the 25th May, websites require explicit, opt-in consent for the use of certain cookies. It seems to be mainly (though not exclusively) aimed at targetted advertising, but it's worth having a read of a good overview of the upcoming cookie privacy laws to see if it will affect you.

Monday, 7 March 2011

Adding custom HTTP headers to soap4r request

When you're using soap4r, you don't have access to the bare httpclient - which means you have absolutely no way of passing in custom HTTP headers (note, not SOAP headers which definitely have an API).

Monkeypatch time!

See the patchfile below. You need to a) vendor soap4r (if you haven't already), then b) update several files with the given patch.

Then you can pass in your customised headers directly via the soap driver before you call the soap method. Here's an example of use:

driver = SOAP::RPC::Driver.new(url, SCHEMA)
driver.add_method 'MySoapMethod', 'MyParam'

driver.options["protocol.http_custom_headers"] = {'MySpecialHeader1' => 'abc', 'MySpecialHeader2' => 'xyz'}
driver.MySoapMethod 'MyValue'

and here's the necessary patches (note: they're in svn-diff style):

Index: vendor/gems/soap4r-1.5.8/lib/soap/rpc/proxy.rb
===================================================================
--- vendor/gems/soap4r-1.5.8/lib/soap/rpc/proxy.rb (revision 4217)
+++ vendor/gems/soap4r-1.5.8/lib/soap/rpc/proxy.rb (working copy)
@@ -32,6 +32,7 @@
   attr_accessor :allow_unqualified_element
   attr_accessor :default_encodingstyle
   attr_accessor :generate_explicit_type
+  attr_accessor :http_headers
   attr_accessor :use_default_namespace
   attr_accessor :return_response_as_xml
   attr_reader :headerhandler
@@ -57,6 +58,7 @@
     @allow_unqualified_element = true
     @default_encodingstyle = nil
     @generate_explicit_type = true
+    @http_headers = nil
     @use_default_namespace = false
     @return_response_as_xml = false
     @headerhandler = Header::HandlerSet.new
@@ -135,7 +137,9 @@
 
       :generate_explicit_type => @generate_explicit_type,
       :use_default_namespace =>
-        op_info.use_default_namespace || @use_default_namespace
+        op_info.use_default_namespace || @use_default_namespace,
+      :http_headers =>  @http_headers
+
     )
     resopt = create_encoding_opt(
       :envelopenamespace => @options["soap.envelope.responsenamespace"],
@@ -168,6 +172,9 @@
     end
     reqopt[:external_content] = nil
     conn_data = marshal(req_env, reqopt)
+    if reqopt[:http_headers].present?
+      conn_data.extheaders = reqopt[:http_headers]
+    end
     if ext = reqopt[:external_content]
       mime = MIMEMessage.new
       ext.each do |k, v|
@@ -299,6 +305,7 @@
     opt[:default_encodingstyle] = @default_encodingstyle
     opt[:allow_unqualified_element] = @allow_unqualified_element
     opt[:generate_explicit_type] = @generate_explicit_type
+    opt[:http_headers] = @http_headers
     opt[:no_indent] = @options["soap.envelope.no_indent"]
     opt[:use_numeric_character_reference] =
       @options["soap.envelope.use_numeric_character_reference"]
Index: vendor/gems/soap4r-1.5.8/lib/soap/rpc/driver.rb
===================================================================
--- vendor/gems/soap4r-1.5.8/lib/soap/rpc/driver.rb (revision 4217)
+++ vendor/gems/soap4r-1.5.8/lib/soap/rpc/driver.rb (working copy)
@@ -211,6 +211,9 @@
     opt.add_hook("protocol.generate_explicit_type") do |key, value|
       @proxy.generate_explicit_type = value
     end
+    opt.add_hook("protocol.http_custom_headers") do |key, value|
+      @proxy.http_headers = value
+    end
     opt.add_hook("protocol.use_default_namespace") do |key, value|
       @proxy.use_default_namespace = value
     end
Index: vendor/gems/soap4r-1.5.8/lib/soap/streamHandler.rb
===================================================================
--- vendor/gems/soap4r-1.5.8/lib/soap/streamHandler.rb (revision 4217)
+++ vendor/gems/soap4r-1.5.8/lib/soap/streamHandler.rb (working copy)
@@ -34,6 +34,8 @@
     attr_accessor :is_nocontent
     attr_accessor :soapaction
 
+    attr_accessor :extheaders
+
     def initialize(send_string = nil)
       @send_string = send_string
       @send_contenttype = nil
@@ -42,6 +44,7 @@
       @is_fault = false
       @is_nocontent = false
       @soapaction = nil
+      @extheaders = nil
     end
   end
 
@@ -230,6 +233,13 @@
     extheader['Content-Type'] = conn_data.send_contenttype
     extheader['SOAPAction'] = "\"#{ conn_data.soapaction }\""
     extheader['Accept-Encoding'] = 'gzip' if send_accept_encoding_gzip?
+    # allow us to pass in custom HTTP headers
+    if conn_data.extheaders.present?
+      conn_data.extheaders.each do |key, value|
+        extheader[key] = value
+      end
+    end
+
     send_string = conn_data.send_string
     @wiredump_dev << "Wire dump:\n\n" if @wiredump_dev
     begin

Wednesday, 2 March 2011

Gotcha: migrations with trailing commas

Trailing commas are bad m'kay?

I had a pretty standard migration, which included something like the following two lines:

    create_table :my_widgets do |t|
      t.string :name, :colour, :flavour
      t.integer :supplier_id
      t.integer :height, :width, :depth,    # note this extra comma...

      t.timestamps
    end

Looked fine at a casual glance, ran just fine - no hiccups. Been using it on dev for a week or so now... no problems... Only noticed an issue when I glanced at db/schema.rb

  create_table "service_report_stats", :force => true do |t|
    t.string   "name"
    t.string   "colour"
    t.string   "flavour"
    t.integer  "supplier_id"
    t.integer  "height"
    t.integer  "width"
    t.integer  "depth"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.integer  "#<ActiveRecord::ConnectionAdapters::TableDefinition:0xb5c35504>" # WTF???
  end

Something seriously wrong with that last "integer" column... mysql shows that yes, that is actually the column's real name:

+-----------------------------------------------------------------+----------+------+-----+---------+----------------+
| Field                                                           | Type     | Null | Key | Default | Extra          |
+-----------------------------------------------------------------+----------+------+-----+---------+----------------+
| id                                                              | int(11)  | NO   | PRI | NULL    | auto_increment |
| supplier_id                                                     | int(11)  | YES  |     | NULL    |                |
.... etc ...
| created_at                                                      | datetime | YES  |     | NULL    |                |
| updated_at                                                      | datetime | YES  |     | NULL    |                |
| #<ActiveRecord::ConnectionAdapters::TableDefinition:0xb5c35504> | int(11)  | YES  |     | NULL    |                |
+-----------------------------------------------------------------+----------+------+-----+---------+----------------+

Right now I have NFI how to actually remove the column... because trying:
alter table my_widgets drop column #<ActiveRecord::ConnectionAdapters::TableDefinition:0xb5c35504>;
Just results in: ERROR 1064 (42000): You have an error in your SQL syntax; , and it won't accept it if I put it in quotes either... so the column currently remains as is.

Luckily I was playing with a branch of the real system - so it's only my dev-box's code that has been mucked about... and I can change the migration before anybody else uses it... but this is seriously weird behaviour on Rails' part. Not a raised exception or even a raised eyebrow... it sailed right through and is continuing on regardless.

To actually fix it, I had to create a migration with the following:

    remove_column :my_widgets,  "#<ActiveRecord::ConnectionAdapters::TableDefinition:0xb5c35504>"

Seems the Rails itself can tell mysql about a weirdly-named column somehow. I'd still like to know the actual SQL involved...

Wednesday, 23 February 2011

Mere globs of gas...

Poets say science takes away from the beauty of stars -- mere globs of gas atoms. Nothing is "mere". I too can see stars on a desert night, and feel them. But do I see less or more? The vastness of the heavens stretches my imagination - stuck on this carousel my little eye can catch one-million-year-old light. A vast pattern -- of which I am a part -- perhaps my stuff was belched from some forgotten star, as one is belching there. Or see them with the greater eye of Palomar, rushing all apart from some common starting point when they were perhaps all together. What is the pattern, or the meaning, or the why? It does not do harm to the mystery to know a little about it. For far more marvelous is the truth than any artists of the past imagined! Why do the poets of the present not speak of it? What men are poets who can speak of Jupiter if he were like a man, but if he is an immense spinning sphere of methane and ammonia must be silent?

-- Richard Feynman

I'm reading The Feynman Lectures on Physics and had to stop and share this quote. It's so perfect.

Saturday, 19 February 2011

Make it easy to be good

I'm trying to be good these days and eat a healthier diet. But doing it "the hard way" is just as difficult as going cold turkey. So I've been trying to find ways that actually make it easy to eat a healthy diet.

One way I'm doing this is through Riverford farm[1] - they deliver a box of fresh fruit and veg to your door once a week (or once a fortnight) for the same price (and much better quality) that you get in the supermarket.

I find that cooking then becomes a surprise instead of a drag. It makes eating your vegies a little bit fun. "What am I going to cook today? Lets see, what do we have here in box number 1?" :)

Something as simple as this helps with inspiration - which is often the only kick-start you really need. But I don't underestimate the "it's delivered to your door" aspect... No fuss, no muss. It really helps make it easy to be good.

On a similar vein, I also get myself graze.com[2] boxes twice a week. They send out a box full of delicious nibbles, randomly chosen from items that you've already rated as something that you've liked. It's novel, it's fun, it's generally pretty healthy. It's enough to eat for lunch and much better than the local greasy-spoon. ...but I don't do it every day, so I don't feel like I'm starving myself or denying myself all of life's pleasures. They also taste delicious. So it doesn't feel like I'm doing any stringent dieting.

Again - just making it easy to do yourself a little good.

How does this apply to programming?

Well, there are heaps of things we *ought* to be doing. Testing, code reviews, refactoring... But somehow it often seems like this stuff just never gets done.

In these cases, it really helps to make it easy to be good.

In my case, I've picked a language and framework where testing is assumed to be done as the default case. It's really easy to do proper testing in Rails. More than that - you're looked-at funny if you don't... like you're actually doing it wrong. So tests, in Rails, tend o get written more often than in other languages (where you often have a hard time justifying to people why you've got to write them).

Once you have tests in place, it's really easy to refactor - because you can do it, knowing that you have a comprehensive test suite to catch you if you break something - gives you the confidence to get it done.

and code reviews? well - if you've been regularly refactoring, then you won't be as ashamed to show off your code to other developers... because it won't be a horrible, hard-to-grok mess... and that makes it much less likely that the code reviews will be put off due to it being "too hard"

Each little step makes it easier and easier to be "good", which makes it far more likely to actually *happen*.


Notes:

[1] Riverford farm only deliver to the UK - but I strongly recommend them - I've been eating their small fruit+veg box once a fortnight (which is enough for just me), and they're always fresh and yummy.
[2]graze.com The graze link is an affiliate link - it will give you a free box so you can try it out yourself. Normally they're around £2.99 each. They ask for a CC to register - but it's easy enough to cancel.

Friday, 11 February 2011

Blind spots

Some people like to hang dingly-dangly things from their car-mirrors.

I always thought it was a bad idea, and it took a little reflection to figure out why.

If you get used to seeing something swaying back and forth in a certain sector of your vision, eventually you learn to ignore movement in that sector. This means that if/when the Bad Thing happens - and suddenly there's an accident happening right in that spot... it takes longer for you to recognise, and react to that accident, because you've learned to ignore stuff happening there.

Well - I was thinking recently about things that were less obvious. Things that I'd put somewhere in my life for amusement value - or even for a good purpose... but which are also serving as a blind-spot. As a place where I "should ignore what's going on".

One of those spots (for me), is in "standing up for myself".

You see, I'm a geek... but more than that, I'm a geek *girl*. I engage in activities that are traditionally considered the province of males... and I get funny looks for doing so. Not from everybody, but enough that I've had to continually resist assumptions (and even outright contempt) all my life.

For years, I've had to work *very* hard to stand up to people that treat me like some kind of weirdo for actually having an interest in things like science, maths, science fiction, martial arts, role-playing games... the list goes on.

I treat any criticism of my choice to pursue these interests as an infringement of my individual rights... and rightly so. It's my business whether I enjoy these things or not. Your opinion does *not* count.

But I've come to notice that it does lend me to have formed a particular blindspot. It's the "don't infringe on the way I do things" blindspot.

I find I'm quicker to resist, to stand up and fight-back, to take offense at people that try to press the boundaries of "the way I do things".

Needless to say, this heuristic can sometimes be misapplied.

After all, I am not perfect, and the way I do things can very well be stupid, wrong or otherwise detrimental to the health and happiness of other people.

But when I'm "called" on it - I currently still have to fight the impulse to fight back. To resist because "I have the right to do my things my way"... and sometimes I lose that internal fight.

So - if I've ever done that to you - my apologies. I'll try to do better next time.

Sunday, 6 February 2011

gotcha: Unpacked gem in vendor/gems has no specification file.

Ok, this one had me stumped for a little while. When I was running rake, I'd get these warnings:

  config.gem: Unpacked gem difftmp in vendor/gems has no specification file. Run 'rake gems:refresh_specs' to fix this.
  config.gem: Unpacked gem difftmp in vendor/gems not in a versioned directory. Giving up.

I'd seen this one before - when I'd thoughtlessly unpacked a gem into vendor/gems, then patched it. But for some reason rails doesn't like it when you unpack gems without using rake gems:unpack. I've never been in the habit of using that, because I didn't want to unpack everything. Later, of course I discovered that you can pass "GEM=blah" and it'll only unpack a single gem... but I thought I had done I this time around...

So I blindly followed the instructions to run rake gems:refresh_specs

However, that then spewed on me with an equally-familiar exception message:

rake aborted!
undefined method `installed_source_index' for #<Gem::SourceIndex:0xb76aa218>
... much stacktrace garbage follows...

I sighed deeply and googled the exception... to get the usual suspects, which suggest that I need to refresh the specification file. So I went back to the original error message to see which actual gem was causing the problem.

... then stopped.

You see it became pretty clear that I'd never actually *read* the original error message. "difftmp" is obviously a temporary diff-file showing me the patch I'd made on one of the gems. Now, you could argue that rake shouldn't be stupid and assume that a flat text file is a gem (requiring a specification)... but it was then also quite clear what to do to fix the "bug".

rm vendor/gems/difftmp

Problem solved

Friday, 4 February 2011

assert_difference for any value

I like assert_difference. It does exactly what it says on the tin - and in a nice, rubyish way.

However, I noticed that you can't assert a difference in something that isn't numeric. You can assert that creating a Customer will change the Customer.count, but you can't assert that updating the customers name will actually change the customer's name. Or, conversely, that updating a customer's name with *bad* data *doesn't* change the customer's name.

In my mind, it shouldn't really matter if the thing doing the changing is an int or a string or some complicated object. If the changing-thing responds to "==", you should be able to check if it changed. As long as you don't actually care what the exact change is that occurred - just whether or not a change *has* occurred.

So I wrote one that did.

assert_any_difference/assert_not_any_difference

Example tests. Note that you can pass a whole array of tests. These should nest, just like assert_difference

    should "not change anything if the account is active" do
      @cr = customer_records(:active)
      assert_not_any_difference ['@cr.customer_number', '@cr.is_active'] do
        assert @cr.register!
      end
    end
    should "update active status if registering a non active customer" do
      @cr = customer_records(:in_active)
      assert_not_any_difference ['@cr.customer_number'] do
        assert_any_difference ['@cr.is_active'] do
          assert @cr.register!
        end
      end
      assert @cr.active?
    end

And the assertions. You'll need to add these to test_helper.rb

  def assert_any_difference(items, &block)
    actual_diff(false, items, &block)
  end
  def assert_not_any_difference(items, &block)
    actual_diff(true, items, &block)
  end

  def actual_diff(test_if_equal, items)
    # save the old values
    old_vals = {}
    items.each {|item| old_vals[item] = eval(item) }
    # run the block
    yield
    test_fn = test_if_equal ? :assert_equal : :assert_not_equal
    # check each one
    items.each do |item|
      new_val = eval(item)
      send(test_fn, old_vals[item], new_val, "should #{'not' if test_if_equal} have been a difference for #{item}, but had: #{new_val}")
    end
  end

Wednesday, 19 January 2011

Rails namespacing test gotchas

We have some controllers that are namespaced as Admin controllers eg: Admin::ProductController.

...and this is a legacy system, and never had any functional tests created for those...

So I was trying to get started on adding some functional tests. I created a test/functional/admin folder, then added a product_controller_test.rb under that, with the usual:

class ProductController < ActionController::TestCase

At first, the tests wouldn't even load properly, and I was getting the following error:

uninitialized constant ActionController (NameError)

That, apparently, is solved by explicitly putting:

require 'test_helper'

at the top of the file. After which it loads fine, and the null-test runs. but after that, I kept getting the following error:

RuntimeError: @controller is nil: make sure you set it in your test's setup method

It seems that you need to namespace your tests too, so instead of the class declaration I have above, you need:

class Admin::ProductController < ActionController::TestCase

The admin folder isn't enough.

Sunday, 16 January 2011

Link: Building mazes with Ruby

JamisBuck has started writing a whole bunch of posts on techniques for maze generation, with examples in Ruby.

It's a fascinating read, and I love the little javascript visualiser for the technique (pretty!).

His idea is that maze-building algorithms are a great way to learn a new language - small projects, but fascinating. I agree.

Friday, 14 January 2011

Bosses prefer overconfidence to accuracy

Well, this should come as no surprise, but it's confirmed that bosses prefer overconfidence to accuracy when asked for estimations.

I've spoken before about how I personally prefer Truth over Harmony, with estimation as a prime example. Mainly because, when it turns out that an estimate was inaccurate... you know who's going to get the blame for "coming in late".

And yet I've found in the past that if I try for accuracy, the truth is taken as "pessimism" (by comparison with the overconfident, optimistic estimates given by others).

What I found particularly scary (and accurate) was the final quote of the article:

"Thus bosses of software managers take accurate estimates to be a signal of a lack of competence."

This is not how the world should work :(

Friday, 7 January 2011

Seven signs your company is really a cult

I just read this article on signs you might be in a cult and Eliezer Yudkowsky's article on cultish countercultishness (where he discusses the cultishness of all groups of humans, and a few theories on how to fight against it happening) and realised that most of the places I *didn't* like to work in - displayed strong cultish tendencies.

Here's a list of the common tendencies I noticed in companies I didn't like working for:

1 - Hierarchical authoritative structure

While hierarchy is inherent in almost all businesses, it was particularly strong in the ones I didn't like working for. What got me was the fact that these companies *stressed the importance* of the hierarchy - ie, the higher up you were, the more important you are and the more you should be faithfully obeyed, rather than, say, the more responsibility you were taking onto your shoulders.

I follow the spider-man principle that "with great power, comes great responsibility"... rather than "with great power comes greater ability to boss everybody else around".

Of course, exaggerated hierarchy goes hand-in-hand with "exaggerated adoration of the respected leaders" (one of the cultish-signs in the articles).

I find this especially the case in companies with strongly charismatic CEOs (or even just one or two managers). Especially so if they can name-drop other big names of the business world they've worked with/for (whether human or corporate)

When you start feeling that you cannot criticise anything that the CEO/manager says simply *because* he's your manager/CEO - then something is rotten in the state of Denmark.

Nothing is absolute - even the perfection of "our great leader". Everybody has faults, and everybody has the potential to learn, yea even from the mouths of babes. So when people are literally told off for having the gall to question "orders from above", you've got something fishy going on.

Sometimes, this idea can affect the whole company:

2 - Absolutism about the company

Either you adore the place with tears-of-joy staining your face, or else you're suspect, "not a team player".

How do you expect the company to improve if you start from a position where everybody must repeat the mantra "the company is perfect and can do no wrong"?

Unfortunately, I've seen this particular problem run hand-in-hand with the next one:

3 - Total immersion

Absolutism can be taken to a personal extreme when you get the sense that you are being told that you are a better person, the more you do for the company. If you spend all your waking hours at work - it shows how virtuous you are, how much of a "team player"... conversely, if you show yourself to be less than ecstatic at a chance to work unpaid overtime, then you must be "not a team player", and thus are suspected of being against the company (somehow)... rather than just, say "a normal person who likes their homelife".

4 - In-groups vs out-groups

AKA "group members encouraged to distrust outside criticism as having hidden motives"

While all companies will of course have in-groups (ie members of the company) vs out-groups... some companies go on to demonise those in the out-groups. I've noticed two obvious groupings that fit in this category:

4a - The inter-company version

"We're much better than *that* company - our competitor over there... everyone there is evil... I mean, they create poor quality products, are trying to take our profits away from us, and are bad for business. They are out to get us! We must beat them and laugh in their faces!"

IMO it is not necessary to demonise your competitors to deal with them. They are just trying to get along in the world, just like "our" company - so they are quite deserving of being treated with the same respect that we'd like to be treated. For example, one should not take every opportunity to take advantage of them. It is certainly not necessary to revel in (or even to actively bring about) their destruction.

4b - The intra-company version

See also: "absolutism about the company" and "total immersion". Especially the use of derogatory phrases for out-groups such as "not a team player".

I've worked in companies where people that resign (even on good terms) are considered to be traitors. Yes, literally traitors, as though you are betraying the trust invested in you by the company. Sometimes they are treated as having taken advantage of the company for money (as though the company did not receive equal value for said money). If you're still working in that company, you're no longer allowed to associate with the "traitors" without also being tainted by the brush of distrust.

Clearly this is pathological behaviour.

In my opinion, healthy companies respect the fact that you are a person first, and a company-member second. People leave companies for reasons other than "betrayal" - and that should be respected, in the same way that an amicable split-up can occur.

Some (good) companies even go on to actually care about what happens to you *after* you leave the company - for example, the well-known google alumni program.

Still, the cultish companies tend to view this as a thought-stopper. If you leave the company, you are now part of the out-group and, by definition, evil. You are simply not allowed to think about it in any other way, or else you are also suspected of being part of the out-group.

Other ways of thought-stopping are inherent in:

5 - Thought-terminating cliches

Some companies are full of these. There are many things that you are *not* allowed to think. Taboos that you shouldn't break or be stigmatised, and they are often hidden behind a cliche that is intended to stop thought in the matter.

The best (general) case I can give is that of "the way things are done here". If this is uttered by anybody at your company, it is intended as a way to stop you from continuing the discussion. It's a big, flashing sign that says "Just don't go there". Trying to show the limitations of such taboo areas just puts you under suspicion.

IMO this is not a healthy attitude towards your company. If you have things that "are just the way we do things here"... then the question naturally arises as to *why*, and whether or not there might actually be a better way. Sure, we shouldn't needlessly poke holes in everything for the sake of it, but somebody asking why things are the way they are isn't trying to tear everything down.

It's also perfectly reasonable to answer the question with "well, it's not optimal, but the time it'd take to change it would outweigh the benefits gained".

That would be an honest answer, and would actually answer the question, instead of "Just don't ask alright?"

6 - Isolation from people not in the in-group

Not as common, but some companies try to keep everything in-house. I've found that the more cultish companies are more likely to look at you strangely if you decide to take lunch outside (you know, with regular people, instead of just with your team-mates every single day of every week...).

I find that this one tends to lead on from strong inter-company in-groupishness. ie, if you view all outsiders as suspect... then anybody that associates with outsiders must also be suspect.

It's also related to the "total immersion" idea. If you truly are a "team player", then surely you want to spend all your waking hours at your beloved company, rather than going out and having a break.

7 - All forms of individuality must be de-emphasized

This is more about the fact that individualism is actively quelled. If you're in a company where the only individual expression you are allowed is in what photo to sit on your desk, and what the trite saying is on your coffee-mug... then you're in trouble.

Cubicles, rules about personal items and the wearing of business-attire certainly all contribute to quelling individuality, but even if these are not present, individuality may be de-emphasised in purely psychological ways.

There are even interesting-but-weird cultural forms of this effect where you are expected to share the passions of your colleagues regardless of whether you, say, don't actually enjoy watching sporting events in favour of reading physics textbooks... or prefer to spend your lunchtime reading rather than discussing said sporting-games (or hairstyles and office gossip, in the case of one set of women I worked with).

It's ok to invite team-members to join into these activities. It's *not* ok to treat people as pariahs if they choose not to participate.

I've even had one company tell me off at my annual review because I wanted to abstain from the company "tipping competition"... regardless of the fact that I have no clue about the sport in question (I was advised to choose randomly... and that <the secretary> had found this strategy very effective to win.)

The most insidious individuality-repression I've found is with excessive worship of groupthink. Where you are expected to agree with all the decisions of your colleagues - and dissuaded from (or actively told off for) finding flaws in "the plan". This especially occurs in conjunction with leader-adoration.

I've spoken about the pitfalls of this in The two faces of optimism.

But it's all just a game isn't it?

Now, I recognise that even in the companies that inculcate these tendencies, the actual people involved (at least at the lower levels) realise that it's all kind of a game... That you don't have to actually *believe* any of this bullshit - just to play along and pretend, in order to "win".

but my response is: why do we have to pretend?

Surely it'd be healthier (for all of us) if we just admit that it's all bullshit and get on with actually enjoying our life?

Especially when a lot of the things we have to pretend actively work against you.

I do not want to pretend that I love unpaid overtime - because I actually hate it - as do most people in the vast majority of jobs that exist in this world.

I really do have better things to do than marching up and down the square... and I think that everyone can actually come up with something or other they'd rather be doing with their life. So why go through the charade? Why force me to lie to you about it? What does that gain?

There are actually companies that don't.

They are unfortunately few and far between... but they do exist.

I've noticed that smaller companies are actually far less prone to cultishness. Perhaps because there are so few people that everyone's more accountable, perhaps because they're too new to have an ingrained cultish culture... I don't know.

There are also companies who have purposely adopted a culture that leads to a good work-life balance.

I do like Eliezer's Cultish countercultishness post because it gives a good overview of the problem (with reference to his particular group), with the final moral being that almost all groups have a tendency to cultishness... that you have to actively work against these natural tendencies to make sure you don't fall into the trap.

So, in short, if you're in a company that is not cultish - my advice it to work hard to make sure it stays that way.

If you find that you are in a company that is irreparably becoming a cult... look elsewhere.

Saturday, 1 January 2011

Link: How to ask a blogger for backlinks

An excellent new post on kissmetrics about How to ask a blogger for backlinks and reviews.

It gives some great tips about how to be professional and non-spammy, and stands in stark contrast to my own recent experience.

...and no, they didn't ask me to write this :)

Thursday, 30 December 2010

Simple private messaging

Ran across this plugin the other day. It gives you very simple, private messaging for Users on your app.

Needs some fiddling to make the messaging private - otherwise anybody can read anybody else's message... but otherwise, pretty neat. It basically does most of the heavy-lifting for you, and lets you get on with the customisation... which is the point of using other people's plugins.

Friday, 24 December 2010

Gotcha: db index name must be a string

Might just be Rails 2.3.8 - an exception is thrown whenever I use a symbol for an index name. I get:

rake aborted!
An error has occurred, all later migrations canceled:
undefined method `length' for :my_index_name

The code causing this would be something like:

add_index :widgets, [:colour, :weight], :name => :index_by_colour_weight

it’s solved by just using a string instead:

add_index :widgets, [:colour, :weight], :name => 'index_by_colour_weight'

Sunday, 19 December 2010

Dosbox and old games

So... my favourite game of all-time is still X-Com: terror the deep. I've been playing it off-and-on now since it first came out 15 years ago.

It is a game with extraordinarily long game-play time. Come to think of it, I think I still haven't actually completed a game yet... it takes months of gameplay to complete... but it's still fun enough that I like to play it anyway.

Now, the thing is, it's a really old game now - it's a DOS game that was able to be played on the then-new Win95... but it hasn't transferred well up the line. I've had to keep around an old laptop for the precise (and only) purpose of playing this game.

For obvious reasons (including the bulk of said ancient laptop), I did not bring that laptop with me to the UK. Which means that I've been deprived of my favourite game for some time.

Lately, however, I learned of Dosbox - which I can now rightly praise as an awesome DOS emulator that actually works on Linux (as well as other, lesser O/Ss). ;)

I had some issues with getting the game to play and save - before realising that I hadn't properly "installed" the game before trying to play it straight of the CD - and thus it didn't have write-privileges, causing it to fail to save a game... or to write the sound-file etc.

but after I figured that out - it's worked just fine. Awesome!

Monday, 13 December 2010

The perils of pagerank

Now that RubyGlasses has gained a bit of PageRank, I've noticed a marked increase in the amount of people emailing me requesting "Link swapping".

I've generally been deleting these along with most of the spam... google doesn't like linkswapping, and I won't do it. (all hail oh mighty google!)

However, I've also received one or two offers of advertising... and, to me, that's different. I'm happy for an advertiser to pay me to put ads on my site that are relevant to my audience.

However, after a recent email-conversation, I now have to make it clear to potential advertisers that these ads are going to be obviously ads.

I will freely confess that I don't get very many offers of advertising. I've had two so far... one that I've accepted (see if you can spot them) and one that I have most definitely not.

The first did want me to *not* use certain ad-like keywords in proximity to their ads... no doubt they're after a bit of my pagerank "link juice" as well as the actual click-throughs that are likely to accrue (yes, I actually asked them about this). That was ok to me, as long as it was obvious to my readers that what was going on was actually an ad... ie paid-for content inviting people to purchase something.

The reason I turned down the second offer, however... was different. In fact, I didn't even need to turn them down - just stated what I was and was not going to do.

The second exchange began with an offer to "have cooperation in marketing". I'll admit that maybe I didn't completely read the email in question because it also explained that they expected me to "add our product information with links to < thecompany > on your blog"... I read this and thought "advertising"... but in the following exchange (I asked if that's what she meant), discovered that she expected to write articles about her products... and put them on this blog.

After explaining that I write my own articles she responded with (and I paraphrase) "Oh ok, so *you'll* write articles about our products on your site, and put links to our products"

I had to then explain that I write articles about Ruby-on-Rails or web-development or freelancing... if her products were relevant to that then I might write an article on them... but I would *not* promise to be favourable.

She then responded with a "suggestion":

I have read your email, I have one suggestion, how about we write articles suitable for your site, and you put it on your site. We can also pay for you on adding them, but how much per article will you charge?

I mean, what does it take to get through to these people? My final email to her reminded her that I write my own articles, and that I will happily post paid advertising at the bottom of my articles - and that she could even dictate the text of the advertising... but that I would not post fake articles written by somebody else about her products.

She said she'd stay in touch...

Saturday, 11 December 2010

NaNoWriteOff

*sigh* I admit defeat.

Though I've "won" three years in a row, this year, I quit after a week... it's kinda sad, but I felt it was a necessary decision.

After a week of the usual noveling, I realised I had so many other commitments this year that one more was really piling on the stress a bit too thick. I weighed up whether or not I needed to complete this one time - and decided I didn't need to prove to myself that I *could* finish a novel as I've done it three times already.

So, for the first time since I discovered the wondrous new world of NaNoWriMo, I failed to finish.

I'm sad about it because this year I actually had a full plot. Most years I just began with an idea and a few characters... It was a Romance (I try a new genre every year) - which lent itself to easy plotting... but I realised a week in, that I just wasn't satisfied with that, and had already begun to add action/adventure elements (the hero was captured by desert pirates... leading to a chase...).

In any case - it'll be there, waiting for me in January - when hopefully I'll dig up a bit more spare time.

Wednesday, 8 December 2010

Less Wrong: the art and practise of Rationality... and Harry Potter

I just found an amazing website that basically constitutes a broad exploration (with much discussion) on the art of "being less wrong".

What's interesting is that I happened upon it because my sister pointed out to me the most interesting Fanfic I've ever read: Harry Potter and the Methods of Rationality.

I don't read fanfic, as a general rule... it's usually just somebody's personal fantasies, and almost never as good as the original fiction.

But this one had me hooked from chapter one. It seems to constitute a kind of course-by-example into the Art of Rationality. No doubt more poignant if you've actually read the original, but fascinating none-the-less. Try it and see for yourself.

If you're not into fanfic at all - then feel free to cut to the chase - skip it and go straight to the Less Wrong wiki.

All this stuff is brought to you by the Singularity Institute which is dedicated to making sure that the predicted technological singularity is Friendly, rather than unfriendly, towards us mere mortals. Less Wrong was created in order to build a community of rationalists that would be able to improve the world in general (including, but not limited to the singularity). The soundbite mission statement being raising the sanity waterline

Thursday, 2 December 2010

I'm not a militant feminist

I assume non-gender bias at the start; I don't care what pronouns you use, and most of those "war of the sexes" ads are just plain funny.

Which is why I was totally surprised by an ad I saw today which suddenly made my "feminism" detector spike off the charts.

I can't find a pic of it online, so I'll have to describe it.

It's for some kind of smartphone.

A smug-looking geek-boy is standing there, with a gorgeous-looking girl with her arm wrapped around him.

The caption: "It's about how smart you are".

...

In case I need to state the obvious - clearly, being totally smart means that if you're a smart guy you get the hot-looking bird... but what makes him look smug is just as clearly *not* about how smart she is.


Disclaimer...

I like geek-boys, and for me it *is* more about how smart they are... but I'd hope that for the geek-boys it'd be about how smart *I* am too!


On further reflection, I think I'd be almost as scandalised if the ad showed a smug geek-girl with an Adonis draped over her.

What mostly annoys me is that it implies that the main benefit of being smart is to be able to entice the beautiful people to hang with you despite how plain-looking you are. In other words - even though it says it's about how smart you are... it's still about how pretty you are... :P

Tuesday, 30 November 2010

Gotcha: heroku with git+svn pushes your working copy

For the MatchFounders website, I've been working with svn on Heroku using git just as a deployment tool... and I came across a bit of a gotcha the other day.

git commit will add your *working copy* to your next deployment.

Luckily it didn't turn out too badly for us - I was just mucking about with some pagination links... and quickly fixed the bug I'd been working on before deploying again... but if I'd been right in the middle of some big hairy code refactor, or something... I'd have had to go find heroku's docs on rollbacks pretty darn quick.

So - just be aware that if you use this method, to add a step to your process-control to make sure you only deploy from a 'clean' working copy.

Tuesday, 23 November 2010

Ruby median

Was trawling through the google analytics search keywords and noticed somebody was looking for an Enumerable#median method when they came to this site. Got me thinking...

I went googling for solutions and found that some of them were just plain wrong... can't have that.

module Enumerable
  def median
    # trivial cases
    return nil if self.empty?

    mid = self.length / 2
    if self.length.odd?
      (entries.sort)[mid]
    else
      s = entries.sort
      (s[mid-1] + s[mid]).to_f / 2.0
    end
  end
end

This one isn't the most time-efficient (the sort can get long). I'd need to implement the selection-algorithm for the most optimal solution... but it'll do for a quick fix. I'll post again here if I get around to the better one.

Friday, 19 November 2010

MatchFounders hits 500

MatchFounders.com hit its first milestone today: 500 registered members. I'm pretty pleased with that, seeing as how it's been a part-time on-the-side project that started on what's basically a hackfest.

Still got heaps to do before it becomes a world-dominating site, of course... but I'm pretty happy with that amount of activity after only a month and a half. Enough to post about it on the matchfounders blog... along with our upcoming dastardly plans.

Saturday, 13 November 2010

mobile broadband roaming

The directors of MoneySpyder have been reading "The 4-Hour Workweek" by Timothy Ferriss and are all fired up about the idea of us working from home (amongst other things). Basically, they're hoping to kick the expense of an office - which is fair enough.

So I casually asked "so, does this mean I can take my laptop on the road?"

I was kinda surprised when they answered yes.

w00t!

So, I finally have the option to live my original dream - spend a month in France, a month in germany, a month in spain...

BUT...

(you knew that was coming)...

I've just checked what it costs to get international roaming on mobile broadband, and it doesn't look pretty.

Actually, that's an understatement... it looks downright atrocious.

I'm currently on three mobile - and I pay around £15 a month for 5G of internet usage. As yet I've never busted that limit - I think I use around 1.5-2G. I used to have a 1G account (with O2) but that wasn't enough for me - eg when I needed to do a full ubuntu upgrade.

However - when I checked into the mobile broadband roaming rates I discovered that they don't bundle your monthly allowance - it costs per mg... and not at the usual overlimit pricing rate of around 10p per meg - it costs you £1.25 per meg!

This would mean my normal monthly usage would come to cost of £2000-£2500 PER MONTH!

Yes, that's over two thousand pounds per month!

Now - I can understand that it costs a fair bit more to use overseas carriers, than to use their own.... but even if *they* bought the data at retail prices, and then charged *us* retail on top of that - this would come to only *twice* our normal per-meg rate...

Not 166 TIMES my normal monthly amount.

There is something seriously wrong there!

Now - the pages all say "well, just don't use as much internet when on the road"... but unfortunately, I have no choice. I am a Web developer - that requires me to do a bit more than just checking email or checking the local weather online. I need to download the latest codebase, get copies of db dumps, upload and deploy sites, go to the online site and test it thoroughly... etc etc. Even if I cut out all recreational internet use (and where's the fun in that) I'd still be using about a Gig a month.

I've noticed that a very few enlightened companies have begun to offer something a *little* better (eg orange travel bundles), but even so - they're still not even approaching regular internet usage. The orange bundle offers 50M at £40 - which would make my monthly spend "only" £1200 - so, half the rate of the Three option... but still in the ridiculous zone.

Now, I've wandered about online in search of a better solution, but I have only a couple of viable options.

Firstly - I could spend my life in a Maccas or Starbucks (or equivalent) for the purposes of the free WiFi connections... rather than actually enjoying the variety of local establishments. Of course - they do expect you to actually purchase some of their wares - and I refuse to eat the former, and the latter is definitely not my cup of coffee-flavoured-milk.

Also - it's quite difficult to actually do real work in a busy cafe. It's ok for a few hours - but it's tough to be there all day. I'd also have to shut down, pack up and potentially lose my table every time I needed to dash to the loo. :P

The second alternative would be to just buy a new dongle from the country I'm visiting... for each country I visit. This feels expensive and wasteful... but if you compare it to the roaming rates - it actually works out cheaper... *far* cheaper.

With Three's quoted roaming rates, it would cost me an average of £85 per day.
Even if a new dongle cost me £100 (for the PAYG version) - I could buy one every two days - and still be paying less.

Ridiculous as this seems, it seems to be my best real option.

If anybody knows of a better solution, let me know!

Dongle-sharing?

But then I got to wondering: perhaps there's others out there wanting to do the same thing. If we each buy a dongle for a different country and then swap with each other - this would be far less expensive. Just buy our own PAYG sims. Or perhaps there are others of you out there already in a different country (that I want to visit) who'd be willing to rent me your own dongle for a month... I'd even pay a refundable deposit!

Any takers?

Wednesday, 3 November 2010

NaNo Wrides again!

It is the month of November, and once again would-be-authors are hurriedly scribbling on pages, or tapping away furiously to meet their daily goal... the elusive 1667!

NaNoWriMo has begun!

I've got my wordcount up on the left again, but you can see more at taryneast's author page.

For those not in the know, "NaNoWriMo" Stands for "National Novel Writing Month" - a writerly self-challenge where people from all around the world pledge to write 50,000 words in the month of November. No, it's not a charity, and it's not a competition... it's just a chance to give it a go and see if you can finally pull that novel out of yourself that you've been procrastinating about for years...

Before you dismiss it as an obscure, minor little thing that only a few weirdo wannabe-writers have heard of... you might want to know that it's more popular than you might think! As of yesterday there were 156,415 authors signed up worldwide, who wrote a collective 55 million words. Yes, that's millions, and yes that's just yesterday!

It's crazy-fun and I recommend it to anyone - especially anyone who thinks they're a terrible writer, or who thinks nobody wants to read what they write... but secretly has a tiny desire to be known as an author. Trust me, NaNoWriMo is for you.

It's only day two - there's still plenty of time to join in the fun! Go on, give it a shot! What have you got to lose? :)