“...I've been working since 2008 with Ruby / Ruby on Rails, love a bit of Elixir / Phoenix and learning Rust. I also poke through other people's code and make PRs for OpenSource Ruby projects that sometimes make it. Currently working for InPay who are based in Denmark...”

Rob Lacey
Senior Software Engineer, Copenhagen, Denmark

MATOTU

Old blog posts I never published, except I have now #7

I wonder if this even still works…maybe.

module Braindeaf
  module Matotu
    require "java"

    # Swing
    java_import javax.swing.JFrame
    java_import javax.swing.JPanel
    java_import javax.swing.JTextField
    # AWT
    java_import java.awt.GridBagLayout
    java_import java.awt.GraphicsEnvironment

    class ShippingGUI < JFrame

      def initialize
        super('ShippingGUI')
        self.init
      end

      def init
        puts header
        @frame = JFrame.new
        @backpanel  = JPanel.new(GridBagLayout.new)
        @input = JTextField.new
        @backpanel.add(@input)
        @frame.add(@backpanel)

        @frame.setLocationRelativeTo nil
        @frame.undecorated = true
        @frame.default_close_operation = JFrame::EXIT_ON_CLOSE
        GraphicsEnvironment.local_graphics_environment.default_screen_device.full_screen_window = @frame
        @frame.setVisible true
      end

      def header
        header = <<-STR
  _____ ______       ________  _________    ________  _________    ___  ___
  |\   _ \  _   \    |\   __  \|\___   ___\ |\   __  \|\___   ___\ |\  \|\  \
  \ \  \\\__\ \  \   \ \  \|\  \|___ \  \_| \ \  \|\  \|___ \  \_| \ \  \\\  \
   \ \  \\|__| \  \   \ \   __  \   \ \  \   \ \  \\\  \   \ \  \   \ \  \\\  \
    \ \  \    \ \  \ __\ \  \ \  \ __\ \  \ __\ \  \\\  \ __\ \  \ __\ \  \\\  \ ___
     \ \__\    \ \__\\__\ \__\ \__\\__\ \__\\__\ \_______\\__\ \__\\__\ \_______\\__\
      \|__|     \|__\|__|\|__|\|__\|__|\|__\|__|\|_______\|__|\|__\|__|\|_______\|__|
        STR
      end
    end
  end
end
Braindeaf::Matotu::ShippingGUI.new

Keep your method to yourself with define_singleton_method

So define_singleton_method is quite cool.

Angel = Class.new do
  def dreaming_of_an
    whatever
  end
end

This is going to fail, whatever is not defined.

Angel.new.dreaming_of_an
(irb):3:in `dreaming_of_an': undefined local variable or method `whatever' for #<Angel:0x0000000107045b98> (NameError)

I can define whatever outside of the object itself.

Angel.new.tap { def whatever; 'aaaaaangel--iiii'; end }.dreaming_of_an
=> "aaaaaangel--iiii"

But what if I define this method directly on the instance

Angel.new.tap { def _1.whatever; 'aaaaaangel'; end }.dreaming_of_an
=> "aaaaaangel"

This seems cleaner

Angel.new.tap { _1.define_singleton_method(:whatever) { 'aaaaaangel' } }.dreaming_of_an
=> "aaaaaangel"

For bonus points, the method lookup fails for _2 because the second argument is nil and it defaults to the global method

irb(main):012> Angel.new.tap { def _1.whatever; 'aaaaaangel'; end }.dreaming_of_an
=> "aaaaaangel"
irb(main):013> Angel.new.tap { def _2.whatever; 'aaaaaangel'; end }.dreaming_of_an
=> "aaaaaangel--iiii"

However, we did manage to assign a singleton method on nil…which is fun.

nil.whatever
=> "aaaaaangel"

Lazy Rails deployment with git

Old blog posts I never published, except I have now #6

Not ideal but quick

root@li38-149:/var/www/thebevy/current# cd ../
root@li38-149:/var/www/thebevy# git clone /var/repos/thebevy.git current
Initialized empty Git repository in /var/www/thebevy/current/.git/
root@server:/var/repos# cat repo.git/hooks/post-receive
#!/bin/sh
GIT_WORK_TREE=/var/www/project/current git checkout -f
cd $GIT_WORK_TREE; touch tmp/restart.txt

It's all about self

I like to be discreet when it codes to snippets of code. I dislike this variable assignment only to use it once on the next line

today = Date.today
today = [today.year, today.year, "%02d" % today.month, "%02d" % today.day]

We need something like a map because the syntax is cleaner, but we don’t really need an array to achieve this surely?

[Date.today].map { |d| d.year, d.year, "%02d" % d.month, "%02d" % d.day }.first

How about this. It allows a block that yields self but we need to force it to return the contents of the block. This is hacky.

Date.today.tap { |d| break [d.year, "%02d" % d.month, "%02d" % d.day] }

So in comes then which is an alias of you guess it yield_self. Nice.

Date.today.then { |d| [d.year, "%02d" % d.month, "%02d" % d.day] }

OK, this is a silly example because this no one would ever do this. You’d do this…

Date.today.strftime("%Y%m%d")

Codemaster's Dizzy returns

Old blog posts I never published, except I have now #5

The first time I used a computer I was about 7 I think. My mum was always ahead of her time and I actually cite her (or blame her) for being such a geek and getting interested in computers in the first place. She bought me my first computer the Amstrad CPC 6128. We got it 2nd hand I remember going round to the owners house and leaving with a pile of boxes of bits, games, manuals and other books.

I don’t recall the time I bought Treasure Island Dizzy but I remember being completely immersed in it, the puzzles and going back and forth trying to work out which items I’d need to get past each stage and open those locked rooms. I might even say this encouraged me to pay attention to detail at such a young age.

After so many years of 3D games. I’ve played them and I just don’t get on with them. Mario 64 on the Nintendo DS just annoyed me. I think World Of Warcraft is the only one I’ve stuck with. I really miss the 2D platform games I enjoyed during my formative years and I wish they still made them. I am so pleased to see now that Dizzy is making a comeback on iPhone, iPad and Android platforms. I did a little dance and I hunted high and low for information on the old games. I found the fabulous YolkFolk Dizzy fan site which has basically everything you need.

It seems also you can get Dizzy clones of the original games (as close to the original as possible) with Spectrum graphics. Presumably they are cloned to avoid copyright issues. There is even a Dizzy game engine named Dizzy Age which programmers can build their own Dizzy games with, and it was this engine that was used to build the clones of the original games.

Getting back on track, the lovely people at Codemasters have brought Dizzy back to life with a remake of Dizzy – Prince of the YolkFolk for modern mobile platforms. It’s between £1.49 and £2.49 depending on what your platform of choice is. I need to pinch Kat’s Motorla Xoom in order to play as my HTC isn’t supported. Dang.

They are running ongoing competitions on their Dizzy Game Facebook page which you should checkout. Always enter competitions…because even I managed to win myself some badges which I can wear with pride down the pub.

SSH Tunnelling

Old blog posts I never published, except I have now #3

ssh root@xen1.robl.me -R :3002:127.0.0.1:3000 sleep 99999
root@li38-149:~# netstat -ltanup
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
......
tcp        0      0 0.0.0.0:3002            0.0.0.0:*               LISTEN      13807/sshd: root@no
......

Redirecting STDERR

So you don’t like STDERR vomming all over your console?

This script almost works but doesn’t redirect anything that is already hold the original file descriptor, e.g. C extensions.

#!/usr/bin/env ruby

STDERR.puts "Something"
$stderr = File.open(File::NULL, 'w')
STDERR.puts "...and something else"

This however reopens the same file descriptor and covers all bases.

#!/usr/bin/env ruby

STDERR.puts "Something"
$stderr.reopen('/dev/null', 'w')
$stderr.sync = true
STDERR.puts "...and nothing"

And we get…

./test.rb 
Something

yes blocks and metaprogramming are very clever...

…but if you can’t read the code without bashing your head against a wall, its pretty useless.

Old blog posts I never published, except I have now #2

Now I admit that this solution has some merit, it filters incoming params in a particular controller action and DRYs up some of the saving and redirecting that is common place in every controller. But when I took this project on it just complicated things so much that it took 4 times as long to make any changes to the app as it needed to.

do_object_edit("recruiter/new_subscription", :pay_subscription, :agreed_terms, :subscription_type_id) do |o|
  o.transaction_detail = "INCOMPLETE"
  o.amount_paid = 0
end
def do_object_edit(template, action, *fields, &block)
  logger.debug "in do_object_edit"
  logger.debug "allowing edit of #{fields.join(', ')}" unless fields.empty?
  if submitted_using_button?("Cancel")
    if action.is_a?(Symbol)
      redirect_to :action => action
    else
      redirect_to action
    end
    return
  elsif request.post?
    fields.map!{|f| f.to_sym}
    params[:object].delete_if{|k,v| !fields.include?(k.to_sym)} unless fields.empty?
    @object.attributes = params[:object]
    begin
      ActiveRecord::Base.transaction do
        if block_given?
          yield @object
        end
        @object.save!
        flash_message "Details Saved"
        if action.is_a?(Symbol)
          redirect_to :action => action
        else
          redirect_to action
        end
        return
      end
    rescue ActiveRecord::RecordInvalid
      logger.warn $!
      flash_message "An Error Occurred"
    end
  end
  render :template => template
end

Yes is DRY because this is repeated everywhere in some form or other, but its not as readable as this.

s = Subscription.new(params[:subscription]) do |s|
  s.transaction_detail = 'INCOMPLETE'
  s.amount_paid = 0
end

unless s.save
  redirect_to failure
else
  redirect_to success
end

So as another developer taking on a dead project, this just made things harder. So my comment really is, coding an application isn’t just for you its for the client and if you can’t read it easily a month after you’ve written it someone else won’t be able to either.

It stinks of coding arrogance over creating a maintainable project. And the client loses…because it takes 5 times longer to get someone to fix it or make changes in the future.

Ruby &&

Old blog posts I never published, except I have now #1

I really like that the && operator in Ruby returns the final argument, or the result of the last evaluation

rl@bloodandguts:~/repos$ irb
>> "take" && "give"
=> "give"
>> "take" && "give" || "take" && "blum"
=> "give"
>> "take" && false || "take" && "blum"
=> "blum"
> "take" && Numeric.new || "take" && "blum"
=> #<Numeric:0x7f2841bffa70>

Shrinking PDFs

Shrinking PDFs so that they aren’t 50Mb for 10 pages is always a good thing to remember. This command line tool form Adobe is particularly helpful

ps2pdf -dPDFSETTINGS=/ebook ~/Desktop/AnimalHealthCertificate.pdf ~/Desktop/AnimalHealthCertificate-compressed.pdf

Now this Animal Health Certificate will actually get through and not bounce.

rl@loathsome ~ % ls -lah ~/Desktop/AnimalHealthCertificate*
-rw-r--r--@ 1 rl  staff   3.1M 21 Sep 11:01 /Users/rl/Desktop/AnimalHealthCertificate-compressed.pdf
-rw-r--r--@ 1 rl  staff    39M 21 Sep 10:59 /Users/rl/Desktop/AnimalHealthCertificate.pdf