Dheeraj Kumar

Ruby, Golang, Scala, Javascript

Subdomains With Go

| Comments

Go has a pretty decent standard library. While it isn’t as extensive as Ruby’s, it certainly covers several requirements a developer might have. In this post, I’ll talk about net/http and subdomains.

In our product EngagementHQ, every customer purchases a site for their community. These sites can be accessed by one or more top-level/sub domains associated with them, but to begin with, we provide them a subdomain so that they can customize their site. These are usually of the format http://sitename.engagementhq.com.

Our app is built using Ruby on Rails, and this is a simplified version of our implementation of multitenancy:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class ApplicationController < ActionController::Base

  prepend_before_filter :set_site

  def set_site
    # `domains` is a cache with all the domains we can expect requests from.
    site_id = domains[request.host.downcase]
    @current_site = Site.find_by(id: site_id)

    if !@current_site
      # Handle 404
    end
  end
end

While building an app with Go recently, I wanted to do the same. I started out with a simple HTTP server:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package main

import (
  "fmt"
  "net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
  fmt.Fprintf(w, "Hello, %q", r.URL.Path[1:])
}

func main() {
  http.HandleFunc("/", handler)
  http.ListenAndServe(":8080", nil)
}

I then used a Pow domain as a proxy to port 8080. So when I visited http://hello.dev, I could access the app. However, when I visited http://tenant1.hello.dev, the server threw a 404.

The first step in figuring this out was to read the net/http docs. It talks about the second parameter to the ListenAndServe call, and why it’s nil. Go provides a HTTP router/multiplexer by default, appropriately named DefaultServeMux, which does not serve subdomains.

The solution is to create a new ServeMux, and make the server use it to resolve any incoming connections. This is how I did it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
type Mux struct {
  http.Handler
}

func (mux Mux) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  mux.ServeHTTP(w, r)
}

func main() {
  mux := http.NewServeMux()
  mux.HandleFunc("/", handler)

  http.ListenAndServe(":8080", mux)
}

Note that http.Handler is an interface, so it cannot be used directly as a receiver, and needs to be implemented in a type.

Now, any check we need to perform about the host should go into the ServeHTTP function. Here’s an example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var subdomains := ... // Load list from the database/cache

func (mux Mux) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  domainParts := strings.Split(r.Host, ".")

  if subdomain := subdomains[domainParts[0]]; subdomain != nil {
    ... // Store the subdomain in a session for future use.

    mux.ServeHTTP(w, r)
  } else {
    // Handle 404
    http.Error(w, "Not found", 404)
  }
}

Another useful trick here is to use the same port to serve multiple parts of the apps using different multiplexers:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
type Subdomains map[string]http.Handler

func (subdomains Subdomains) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  domainParts := strings.Split(r.Host, ".")

  if mux := subdomains[domainParts[0]]; mux != nil {
    // Let the appropriate mux serve the request
    mux.ServeHTTP(w, r)
  } else {
    // Handle 404
    http.Error(w, "Not found", 404)
  }
}

func main() {
  adminMux := http.NewServeMux()
  adminMux.HandleFunc("/admin/pathone", adminHandlerOne)
  adminMux.HandleFunc("/admin/pathtwo", adminHandlerTwo)

  analyticsMux := http.NewServeMux()
  analyticsMux.HandleFunc("/analytics/pathone", analyticsHandlerOne)
  analyticsMux.HandleFunc("/analytics/pathtwo", analyticsHandlerTwo)

  subdomains := make(Subdomains)
  subdomains["admin"] = adminMux
  subdomains["analytics"] = analyticsMux

  http.ListenAndServe(":8080", subdomains)
}

One definitely has to do more work with Go than Rails, but it’s quite cool to have less magic in my codebase, and more nuts & bolts. I had fun figuring this out, and I hope someone finds this useful!

Paste Mode in Scala REPL

| Comments

Scala has a great REPL, which is extremely useful especially for a beginner like me. Coming from the Ruby land and the browser consoles, I found it familiar, like a friendly face in a different country.

I had issues while trying to execute multiline code in the REPL. I did try writing them in the same line, but it gets unwieldy very quickly. Upon googling, I discovered via a very useful blog post, that it has a paste mode that solves this exact problem.

So now, all I have to do is to type :paste, followed by my code, and terminate the mode with a Ctrl+D.

However, that’s not all it does! I can even evaluate the contents of a file:

1
2
3
scala> :paste hello.scala
Pasting file hello.scala...
defined object Hi

I could use :load instead, but it has a limitation. Quoting the changelog:

:load can only interpret a file from top to bottom which is for example a problem when there is a reference to a definition that is defined later. :paste is overworked to solve this limitation. It now can not only load a file but also handle it as a single unit.

I can also ask the REPL to consider my input as a scala file, instead of a script. This is activated by using the -raw parameter. The example from the changelog explains it succintly:

1
2
3
4
5
6
7
8
9
10
11
scala> :paste -raw
// Entering paste mode (ctrl-D to finish)

package abc
case class Foo(bar: Int)

// Exiting paste mode, now interpreting.


scala> abc.Foo(5)
res5: abc.Foo = Foo(5)

Note that if I don’t use the parameter, this happens:

1
2
3
4
5
6
7
8
9
10
11
scala> :paste
// Entering paste mode (ctrl-D to finish)

package abc
case class Foo(bar: Int)

// Exiting paste mode, now interpreting.

<console>:1: error: illegal start of definition
       package abc
       ^

Hacking Sneaky Sneaky

| Comments

I recently came across a game called Sneaky Sneaky while browsing around Steam, and on watching a few videos, decided to purchase it. It’s like a 2D Assassin’s Creed, with Zelda-esque graphics and a few RPG elements.

I played it on my PC, but it supports only mouse clicks, which led me to guess that it’s probably a port of a mobile game. It turned out to be correct, as Sneaky Sneaky is originally for iOS.

It took me a few hours to finish the game. It’s so much fun to play, and I loved it. It even gave me an idea for a new game! I was, however, annoyed by the AI and the controls – two areas where the game could have done better. In some levels, Sneaky wouldn’t turn or stop fast enough to hide from the enemies, leading to unnecessary fights. The combat animations were quite slow, the enemies quite strong in the second half of the game, and I found myself getting bored & my character killed very quicky.

So, I decided to hack the game and cheat a bit. I just wanted an infinite health hack so that I could at least not be penalized for any control issues, and find a bush to hide in. However, I ended up finding so much more…

I started by locating the game’s executable inside the Steam directory, and running Exeinfo PE on it:

No packing, that’s pretty good! I don’t know if that’s a Steam limitation. Let’s look into it some more:

Debug info is present! that’s a surprise, but I’m not complaining!

Everything else seemed pretty standard, so I fired up Cheat Engine and attached it to the game. Let’s get hacking!

I noticed that damages were in counts of half-hearts, so I guessed that’s how the health was being stored. So if Sneaky had 3 hearts, it was being stored as 3 * 2 half-hearts = 6. So I searched for 6, got hit once, searched for 4, got hit once more, searched, used a potion, etc. I was left with one address for the health. That was simple!

The address I found was clearly dynamic, so the next time I played the game, or even in the next stage/room, I could have a different address, which I’ll have to find again. This is called Dynamic Memory Allocation (DMA), which needs to be defeated. There are several ways to do this, and I started with the simplest – pointers.

I wanted to find a series of pointers, that will lead me to the correct address, regardless of the room/stage I’m in, or even a different instance of a game altogether.

The first time I scanned for a level 5 pointer, I found 48 million pointers, which I rescanned multiple times, trying out various moves to invalidate as many results as possible – moving to a new room, moving to a new stage, quitting and starting a new game instance…

Eventually, I ended up with zero pointers left.

One possible reason for this is – the game could have used an embedded scripting language like Lua, which has a VM to manage its memory. Given that it’s also on iOS, it’s a good possibility. I didn’t want to spend time investigating, so I moved on to the next weapon in my arsenal – debugging.

I used a Cheat Engine feature to find out what opcodes accessed the current health address, and then got hit by an enemy.

The first one, with the 2904 count (and counting!), had to be a part of the game loop. I let a slime hit me thrice, which resulted in the remaining 4 opcodes.

I know that for a simple infinite health hack, all I have to do is to patch the game loop, and write a high-enough number to my health’s address. However, there might be complications. What if the same opcodes handled both the player’s and the enemies’ health addresses?

I first had to confirm if that was the case. I was reasonably confident, since most games are OOP systems, which lead to monsters and players sharing the same base classes.

To do this, I used another Cheat Engine feature to find what addresses were accessed by a particular opcode. I used this on the opcode inside the game loop. This is what I got:

So I was right – four addresses were being accessed, and I had four entities on screen – three slimes and Sneaky.

Now, I had to figure out how to distinguish an enemy from a player. There are again several ways to do this, but in this case, I needed to analyze the data structure for an entity.

All the opcodes I got dealt with [something + A4], so it was logical that something be the base address for that entity. I used Cheat Engine’s Structure dissection utility, and started marking the important offsets. I did this for about 4 types of monsters, and ended up with these:

As you can see, I ended up with a few more addresses than just how to differentiate between entity types. I searched for actual values to find the arrows & items offsets, but the max health was found from another source. We’ll get there in a moment. The important thing is, I managed to find two offsets which were zero for the player, but had values for the monsters. That’s the differentiator we need! Now, I had everything I needed to make the infinite health hack.

I mentioned earlier that the monsters and the slow combat annoyed me, and now that I know their health addresses, I wanted to experiment with a one-hit kill. I started by setting their health to zero.

I seemed to have ended up with zombie enemies! Clearly, the monsters’ removal doesn’t respond to changes in the health. They would happen together when they are attacked. That makes sense, and I could hit them just once for them to die, but I still had to go through the slow combat scene. What if I could just kill them automatically?

To do this, I looked at the opcodes that were executed when some damage was incurred:

1
2
3
4
5
6
7
8
9
10
11
; Read the current health value
sneaky.exe+47BC - 0FBE BE A4000000  - movsx edi,byte ptr [esi+000000A4]

; Write the health back, after subtracting the damage
sneaky.exe+47ED - 88 86 A4000000  - mov [esi+000000A4],al

; Read the new health value again?
sneaky.exe+47F7 - 0FBE 86 A4000000  - movsx eax,byte ptr [esi+000000A4]

; Check if the entity is dead
sneaky.exe+4828 - 80 BE A4000000 00 - cmp byte ptr [esi+000000A4],00

I saw the distance between the 4 opcodes, and they look like they are a part of a single routine. This was clearly the ‘attack’ routine of the game. To find how to call it for enemies, I could have used Cheat Engine, but I felt another tool would be more useful. So I fired up OllyDBG 2.0.

I tried doing this with Olly 1.10, but v2’s analysis capabilities are much better than the first. It was able to recognize some routines in the game that v1.10 couldn’t.

I loaded sneaky.exe inside Olly, let it analyze the code, went to the routine, found the entry point and set a breakpoint. I then hit a monster in-game and watched it break:

Looking at the stack trace at the bottom right, I saw that there were three parameters passed to this routine. Arg3 was clearly the damage I dealt – 2 hearts represented as 4 half-hearts. I had to understand what the other 2 arguments where.

I first thought that it would be the two parties involved in the exchange – the attacker and the victim. In that case, however, the victim’s address wouldn’t be passed using ECX. Also, the addresses of the data structures passed were too distant from the ones I found previously.

After playing around some more, I noticed that Arg1 was zero for melee attacks (like in the screenshot), but was a pointer for arrow attacks. To figure this out, I went back to Cheat Engine and tried its structure dissection feature on the address from the stack.

I couldn’t figure out what this exactly is, but I guessed it was some sort of attack object, along with the sprites & animations involved. Now I had the extra work of finding these addresses and passing it to the method. I didn’t want to do that, so I went through the code to understand how they were being used.

The entire routine is too large (540 bytes) to explain, so I’ve only shown the important parts:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
$+472F      /$  mov     eax, sneaky.00201101               ; Entry point
$+4734      |.  call    sneaky.001EDC70                    ; Setup a SEH
$+4739      |.  sub     esp, 10                            ; This method uses 4 local vars
$+473C      |.  push    ebx                                ; Prologue
$+473D      |.  push    esi                                ; Prologue 
$+473E      |.  push    edi                                ; Prologue
$+473F      |.  mov     esi, ecx                           ; Pointer to entity is passed around via ECX
$+4787      |.  mov     eax, dword ptr [ebp+8]             ; Read Arg1
$+478E      |.  test    eax, eax
$+4790      |.- jz      short sneaky.0012479E              ; It checks for null! woohoo!
$+4795      |.- jnz     short sneaky.0012479E
$+479C      |.  call    dword ptr [edx]                    ; Call animations?
$+479E      |>  mov     eax, dword ptr [ebp+0C]            ; Read Arg2
$+47A5      |.  test    eax, eax
$+47A7      |.- jz      short sneaky.001247B5              ; It checks for null! woohoo!
$+47AC      |.- jnz     short sneaky.001247B5
$+47B3      |.  call    dword ptr [edx]                    ; Call animations?
$+47BC      |>  movsx   edi, byte ptr [esi+0A4]            ; Read the current health value
$+47C3      |.  movsx   ecx, byte ptr [esi+94]             ; Read the max health value
$+47CA      |.  mov     eax, edi
$+47CC      |.  sub     eax, dword ptr [ebp+10]            ; Subtract the damage from Arg3
$+47D4      |.  cmp     eax, ebx
$+47DF      |.- jg      short sneaky.001247E4              ; Check if the current health is > 0.
$+47E4      |>  cmp     ecx, dword ptr [eax]
$+47E6      |.- jge     short sneaky.001247EB              ; Check if the max health >= current health
$+47E8      |.  lea     eax, [ebp-14]                      ; If not, make current health = max health
$+47EB      |>  mov     al, byte ptr [eax]
$+47ED      |.  mov     byte ptr [esi+0A4], al             ; Write the current health value back to memory
$+47F3      |.  cmp     edi, ebx                           ; This pattern is a while loop, most likely for painting the UI, and visually displaying each heart/half a heart being lost.
$+47F5      |.- jle     short sneaky.00124825
$+47F7      |>  /movsx   eax, byte ptr [esi+0A4]
$+481B      |.  |call    sneaky.001C17A0                   ; Paint UI?
$+4820      |>  |inc     ebx
$+4821      |.  |cmp     ebx, edi
$+4823      |.- \jl      short sneaky.001247F7
$+4828      |.  cmp     byte ptr [esi+0A4], 0              ; Actual death checks start here. 
$+482F      |.- jg      sneaky.00124982                    ; Exit the routine if healthy
$+....      |.-                                            ; More death checks
$+....      |.-                                            ; More calling animations on the attack object(s)
$+4A0E      \.  retn    0C                                 ; 12 bytes were passed as arguments to this method.

That was quite straightforward to follow. The important thing I got out of this, was that the attack objects could be null pointers! That simplified everything. Now, writing a hack was trivial. The easiest way was an Auto Assembler script in Cheat Engine:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// ; Boilerplate begins.

// ; Game loop address to hook into. 
define(address, "sneaky.exe"+2836)
define(bytes, 0F BE 86 A4 00 00 00)

[ENABLE]

// ; Make sure the game versions match
assert(address, bytes)
// ; Allocate some memory for our hack
alloc(newmem,$ 1000)

label(code)
label(return)

registersymbol(GodModeEnabled)
registersymbol(AutoKillEnabled)

label(Hacks)

label(GodModeEnter)
label(GodModeExit)
label(AutoKillEnter)
label(AutoKillExit)

label(DetectPlayer)
label(SetPlayer)
label(SetEnemy)

label(GodModeEnabled)
label(AutoKillEnabled)
label(PlayerDetected)

newmem:
// ; Define a bunch of variables 
PlayerDetected:
 dd 0

GodModeEnabled:
 dd 0

AutoKillEnabled:
 dd 0

code:
  // ; Are we dealing with the player or the enemy?

  DetectPlayer:
    cmp [esi+1C], 00
    jne SetEnemy

  SetPlayer:
    mov [PlayerDetected], 01
    jmp Hacks

  SetEnemy:
    mov [PlayerDetected], 00
    jmp Hacks

  Hacks:

  GodModeEnter:
    // ; Bunch of checks to enable god mode
    cmp [GodModeEnabled], 01
    jne GodModeExit

    cmp [PlayerDetected], 01
    jne GodModeExit

    // ; Refill health by replacing it by max health. 
    mov eax, [esi+00000094]
    mov [esi+000000A4], eax

  GodModeExit:

  AutoKillEnter:
    // ; Bunch of checks to auto kill
    cmp [AutoKillEnabled], 01
    jne AutoKillExit

    cmp [PlayerDetected], 01
    je AutoKillExit

    // ; Let's send out an attack!

    // ; No idea what the current ECX is, better be safe.
    push ecx

    // ; The first piece of data the attack method needs - a pointer to the entity in ECX
    mov ecx, esi

    // ; The two attack objects
    push 0
    push 0

    // ; The second piece of data the method needs - the damage done. Let's do damage equal to the enemy's max health. I could have just sent in a large number, but this is safer and less hackier.
    movsx eax, byte ptr [esi+00000094]
    push eax

    call "sneaky.exe"+472F

    // ; Restore ECX
    pop ecx

  AutoKillExit:

  // ; This was the original instruction
  movsx eax, byte ptr [esi+000000A4]

  jmp return

address:
  jmp code
  nop
  nop

return:

[DISABLE]

address:
  db bytes
  // ; movsx eax, byte ptr [esi+000000A4]

dealloc(newmem)

unregistersymbol(GodModeEnabled)
unregistersymbol(AutoKillEnabled)

This is not a clean implementation, and can be refactored a bit. However, for a quick & dirty hack, it works perfectly!

When enabled, the autokill hack makes all enemies in the current room kill themselves. I could call it the suicide hack, but autokill sounds fancier, and more importantly, much less morbid!

I wouldn’t implement this in a trainer in this form, for it destroys all the fun in the game. Cheats are for reducing the difficulty level by providing an unfair advantage to the player, but not for ruining the entire gameplay experience. What good is a stealth-based game, if there is nobody to hide from?

I’d definitely implement the god mode. As I mentioned above, it’d keep Sneaky alive enough to find a bush to hide in. I would probably bind the autokill hack to a hotkey, instead of letting it kill everything in sight. This way, if the player finds a room too difficult to pass, they could clear it easily with the press of a button. I could even kill just one enemy with every invocation, instead of all of them.

Also, I’ve marked the arrows & items’ offsets in the entity structure above, but considering how easy they are to come across, I wouldn’t hack them at all.

I spent about 4 hours finishing the game, 3 hours hacking the game, but 8 hours writing, refining & annotating this post. I suppose it would be easier if I were more regular in writing.

If you find the game interesting (or the hacking, but who am I kidding?), you can pick it up on Steam (with a 10% discount till 2nd January 2015!)

A Quick Dive Into Rake Internals

| Comments

In the latest Ruby Weekly, I saw an article being referenced, titled Disable dangerous rake tasks in production. The author addresses a valid concern for the development community, and I’m sure we’ve all had our fair share of… misadventures in production :D

The best way to implement guards is obviously using Rake’s prerequisites system. It did lead me to wonder how an alternate syntax for custom guards might be implemented. This is what I had in mind:

An alternate, mildly pointless syntax
1
2
3
4
5
6
desc 'Does something dangerous'
guard 'guards:no_production'
guard 'guards:feature_x_enabled'
task :danger do
  # ... something potentially dangerous ...
end

I want to run this task only when feature X is enabled, and make sure it doesn’t run in production. This is how it can be done using prerequisites:

Perfectly working syntax
1
2
3
4
desc 'Does something dangerous'
task :danger => [ 'guards:no_production', 'guards:feature_x_enabled' ] do
  # ... something potentially dangerous ...
end

…but my love for pretty DSLs shook its head firmly against it :P

I also had an ulterior motive – to figure out how the desc method works. Since the definition of a task is a separate method call from the description, how do the descriptions get associated? I’ve always wanted to look into it, but it was pretty far down my list. “Oh well” I thought, “no time like the present!”

Hence I began the dive into Rake’s source code, starting with the desc method:

dsl_definition.rb#L161link
1
2
3
4
5
6
7
8
9
10
11
# Describes the next rake task.  Duplicate descriptions are discarded.
#
# Example:
#   desc "Run the Unit Tests"
#   task test: [:build]
#     # ... run tests
#   end
#
def desc(description) # :doc:
  Rake.application.last_description = description
end

Of course, it had to store the last description. It seems so obvious now!

Here’s how last_description is defined & used:

task_manager.rblink
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
module Rake

  # The TaskManager module is a mixin for managing tasks.
  module TaskManager
    # Track the last comment made in the Rakefile.
    attr_accessor :last_description

    def initialize # :nodoc:
      super
      @last_description = nil
    end

    def define_task(task_class, *args, &block) # :nodoc:
      task = #...
      task.add_description(get_description(task))
      task
    end

    private

    # Return the current description, clearing it in the process.
    def get_description(task)
      desc = @last_description
      @last_description = nil
      desc
    end
  end
end

That looks pretty straightforward:
1. Initialize a last_description variable, reset it for every task.
2. Add the last description to every task.

This module is included within the Application object like this:

application.rblink
1
2
3
4
5
module Rake
  class Application
    include TaskManager
  end
end

Let’s now see how descriptions are defined & used:

task.rblink
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
module Rake
  module Task
    def initialize(task_name, app)
      @comments        = []
    end

    # Clear the existing prerequisites and actions of a rake task.
    def clear
      clear_comments
    end

    # Clear the existing comments on a rake task.
    def clear_comments
      @comments = []
      self
    end

    # Add a description to the task.  The description can consist of an option
    # argument list (enclosed brackets) and an optional comment.
    def add_description(description)
      return unless description
      comment = description.strip
      add_comment(comment) if comment && ! comment.empty?
    end

    def comment=(comment) # :nodoc:
      add_comment(comment)
    end

    def add_comment(comment) # :nodoc:
      return if comment.nil?
      @comments << comment unless @comments.include?(comment)
    end
    private :add_comment

    # Full collection of comments. Multiple comments are separated by
    # newlines.
    def full_comment
      transform_comments("\n")
    end
  end
end

Again, very straightforward:
1. Define an array of comments
2. Add any new comments to the array
3. Collate them for display.

Armed with this knowledge, let’s see how we can achieve the pretty syntax we wanted. We’ll start by patching the DSL module to add a new guard method:

dsl.rb
1
2
3
4
5
6
7
8
9
module Rake
  module DSL
    private

    def guard(args) # :doc:
      Rake.application.last_guards << args
    end
  end
end

Let’s define the last_guards now:

task_guards.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
module Rake
  # The TaskGuards module is a mixin for adding guards for tasks.
  module TaskGuards
    # Track the last set of guards defined in the Rakefile.
    attr_accessor :last_guards

    def initialize # :nodoc:
      super
      @last_guards = []
    end

    private

    # Return the current guards, clearing it in the process.
    def get_guards(task)
      guards = @last_guards
      @last_guards = []
      guards
    end
  end
end

We’re following pretty much the same code as the desc feature’s. Now to write some code to actually add the guards as prerequisites:

task_guards.rb
1
2
3
4
5
6
7
module Rake
  module TaskGuards
    def define_task(task_class, *args, &block) # :nodoc:
      super.enhance get_guards(task)
    end
  end
end

We first start by calling super with no arguments, which calls the ancestor’s define_task method with all arguments preserved. This would return a Rake::Task object, on which we call the #enhance method. This accepts an array of prerequisites, which are provided by our #get_guards method.

Let’s hook these up by including the TaskGuards module:

application.rb
1
2
3
4
5
module Rake
  class Application
    include TaskGuards
  end
end

That should do it! Here’s the entire code, in all its glory:

Il gigante contorta
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
module Rake
  # The TaskGuards module is a mixin for adding guards for tasks.
  module TaskGuards
    # Track the last set of guards defined in the Rakefile.
    attr_accessor :last_guards

    def initialize # :nodoc:
      super
      @last_guards = []
    end

    def define_task(task_class, *args, &block) # :nodoc:
      super.enhance get_guards(task)
    end

    private

    # Return the current guards, clearing it in the process.
    def get_guards(task)
      guards = @last_guards
      @last_guards = []
      guards
    end
  end
end


module Rake
  module DSL
    private

    def guard(args) # :doc:
      Rake.application.last_guards << args
    end
  end
end

module Rake
  class Application
    include TaskGuards
  end
end

I’d stick this into a file, and include that in my Rakefile if I actually wanted to use this feature :D

This is how I’d write the two guards I used as an example. Note how we fail fast via the exit method:

guards.rake
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
namespace :guards do

  task :feature_x_enabled do
    # ...
  end

  task :no_production do
    if is_environment(:production)
      puts 'This task cannot be run in the production environment!'
      exit
    end
  end
end

def is_environment(environment)
  if defined?(Rails)
    Rails.env == environment
  elsif rack_env = ENV['RACK_ENV']
    rack_env == environment
  else
    [ '1', 'TRUE' ].include? ENV[environment.upcase]
  end
end

This was a mildly pointless experiment I tried to get my DSL fix, and also to understand how Rake works under the hood. I discovered how modular the library is, and how readable it makes the code. All in all, a well-spent Sunday evening!

Join Me as I Learn Scala

| Comments

It has been a while since I learnt a new language. I learnt Ember.js and React.js during the past year, but it’s time for something completely different.

When I started out writing desktop apps in 2002, I had an intense dislike for Java. It was originally positioned as a “Write once, run anywhere” language. However, writing desktop programs using Java was complex, and the GUI apps that I wrote looked so different than the native look & feel, that I was convinced I would never ever use it. Java was also responsible for the slowest parts of the web – Applets (Flash loaded quicker!) and annoyed me to no end with JRE’s update process. I understood Java as something positioned for the enterprise, and I wanted no part of it.

Fast forward twelve years, Java is in a near-dead state in both Desktop and Web environments. I’ve shifted to the web, and no longer write desktop apps professionally. Since the Kingdom of Nouns is a nightmarish dystopian landscape, I’d rather not go there. However, since I want to learn something that runs on the JVM, I looked at Scala.

I haven’t started learning it yet. I’ve tried out a few examples, but that’s it. I’d like to try out an experiment, where I blog about my learning, the resources I use, and comparing concepts to other languages I’ve used. I hope to publish at least one article every week. The idea is to get feedback early from Scala veterans, and other Scala beginners. Also, it’d spur me into writing more, which is something that I’ve been putting off in the last year.

To kick-start this experiment, I’ve updated my blog’s tagline to include Scala, and now sitting down with some ice cream to celebrate. That’s a good start, right?

A Help Message Which Actually Is Helpful

| Comments

One fine morning last week, I booted my Macbook Pro I had shut down the previous night. The sun was young in the sky, birds chirped and cawed atop freshly-green trees, whose canopies cast their shade on a plethora of beings – from a baby squirrel looking for its nuts, to a driver in a Camry, screaming his off at a jaywalker.

All in all, a great day to code.

…or so I thought.

My Rails app didn’t boot, and this was the error I got:

1
Mysql2::Error: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2 "No such file or directory")

It wasn’t expected, as launchd was supposed to start the database server on boot. “That’s not so bad”, I thought, as I typed the familiar line into zsh:

1
2
3
4
5
$ sudo mysql.server start
/usr/local/Cellar/mariadb/10.0.10/bin/my_print_defaults: Can't read dir of '/usr/local/etc/my.cnf.d' (Errcode: 2 "No such file or directory")
Fatal error in defaults handling. Program aborted
Starting MySQL
...................................^C

That’s just way too many dots, and deserved a CTRL+C.

…and what was that error? I didn’t remember doing anything to blow up my MariaDB installation.

I sighed, rolled up my sleeves, and started debugging.

Actually, the sleeves were already rolled up. I just sighed and started debugging.

My first stop was to call the doctor:

1
2
3
4
$ brew doctor
Please note that these warnings are just used to help the Homebrew maintainers
with debugging if you file an issue. If everything you use Homebrew for is
working fine: please don't worry and just ignore them. Thanks!

Nothing. Hmm. Next, I looked for more info about the package:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
$ brew info mariadb
mariadb: stable 10.0.13 (bottled)
http://mariadb.org/
Conflicts with: mysql, mysql-cluster, mysql-connector-c, percona-server
/usr/local/Cellar/mariadb/10.0.10 (525 files, 125M) *
  Poured from bottle
From: https://github.com/Homebrew/homebrew/blob/master/Library/Formula/mariadb.rb
==> Dependencies
Build: cmake ✘
==> Options
--enable-local-infile
  Build with local infile loading support
--universal
  Build a universal binary
--with-archive-storage-engine
  Compile with the ARCHIVE storage engine enabled
--with-bench
  Keep benchmark app when installing
--with-blackhole-storage-engine
  Compile with the BLACKHOLE storage engine enabled
--with-embedded
  Build the embedded server
--with-libedit
  Compile with editline wrapper instead of readline
--with-tests
  Keep test when installing
==> Caveats
A "/etc/my.cnf" from another install may interfere with a Homebrew-built
server starting up correctly.

To connect:
    mysql -uroot

To reload mariadb after an upgrade:
    launchctl unload ~/Library/LaunchAgents/homebrew.mxcl.mariadb.plist
    launchctl load ~/Library/LaunchAgents/homebrew.mxcl.mariadb.plist
Or, if you don't want/need launchctl, you can just run:
    mysql.server start

That’s a lot of info, but not helpful to fix the issue at hand.

I knew that there are usually more messages not displayed here, so I ran:

1
2
3
4
5
6
7
8
9
10
11
12
$ brew postinstall mariadb
==> /usr/local/Cellar/mariadb/10.0.13/bin/mysql_install_db --verbose --user=dheeraj --basedir=/usr/local/Cellar/mariadb
--user=dheeraj
--basedir=/usr/local/Cellar/mariadb/10.0.13
--datadir=/usr/local/var/mysql
--tmpdir=/tmp


READ THIS: https://github.com/Homebrew/homebrew/wiki/troubleshooting

These open issues may also help:
mariadb: missing /usr/local/etc/my.cnf.d, removed by brew prune (https://github.com/Homebrew/homebrew/issues/31760)

Hello there! That’s my exact error! The issue on GitHub is very helpful, it reminded me that I ran brew prune the previous night, which apparently removed a directory MariaDB requires. It also had a simple fix, which I tried:

1
2
3
4
$ mkdir /usr/local/etc/my.cnf.d
$ sudo mysql.server start
Starting MySQL
. SUCCESS!

And the universe was restored to order, again.

My takeaway from this whole incident was that, all it took to fix my problem was a strategically placed help message. Homebrew needn’t have cared about it, but the fact they did is what differentiates great software from good software.

User experience is not just about GUIs, flat design and Fitts’s law. It’s about being easy to use, and being helpful to the user when they need it the most.

Thanks, Homebrew, for nailing it.

Coaching RailsGirls Bangalore

| Comments

On Saturday, 3rd August 2013, ~130 girls gathered at ThoughtWorks, Bangalore, and learnt Ruby on Rails. This was a part of an international community, called RailsGirls. This was the largest ever RailsGirls event in the entire world, and was a huge success.

These girls were coached by ~30 Rails developers, and I was one of them.

Teaching them was an amazing & eye-opening experience, which I’ll detail in another post, but before that, I’ll recommend a bunch of resources to continue the journey they started.

Ruby on Rails Tutorial – A frequently-updated guide to learning Rails, by Michael Hartl. This is THE best resource for beginners. The online version is free to read, while the PDF & accompanying screencasts are paid.

RailsCasts – Screencasts on Ruby on Rails & related technologies. This is a one-stop resource for most design patterns, technologies and Rails features you’ll want to learn. Ryan Bates is doing some wonderful work with this. Most screencasts are free, while you can subscribe to access pro & revised content (which are totally worth it!).

Ruby API Documentation – The official Ruby documentation. Extremely useful. Every day with this resource leads to new discoveries

Rails Guides – The official Rails guides to various features. Very useful. Covers a lot of topics in depth. While starting to learn Rails, I used to skim these, and slowly began to read & understand them in depth. You should have this open in a browser tab all the time.

Rails API Documentation – The official Rails documentation. Extremely useful. Covers every single public method, class and constant in Rails. You should have this open in a browser tab all the time.

RubyGems – Gems are Ruby libraries, and this is a gem index. I use it to search for related gems, and find their latest versions.

Ruby Toolbox – A curated Ruby gem aggregator, which presents more useful statistics than RubyGems does. They are categorized, which makes it very easy to compare & choose a gem to handle a particular task.

RubyDoc – While it has a similar address as the official Ruby docs, this site is an index of documentation of all the gems. A very valuable resource

The first resource is only for beginners, but the most others are used by novices & experienced developers alike. In fact, if you walk into any company using Rails, you’ll see most browsers with at least one of these open

Now, let me list a few newsgroups you should be a part of.

Bangalore Ruby User Group – BRUG is India’s largest & most active Ruby user group. Everything from syntax errors and technology decisions to job posts and event announcements are discussed here.

Ruby on Rails Talk – International RoR newsgroup. It’s like BRUG, except much, much bigger.

I have more resources for moderately skilled Rails developers, but that’s a blog post of its own!

All You EVER Wanted to Know About Client-side Frameworks

| Comments

I’ve always wanted to speak at a conference. I’ve never done anything to make it happen, so when I got an opportunity to, I took it up.

JSFoo 2013 is on 20-21 September 2013. While their website hasn’t been updated since last year’s event, the Hasgeek Funnel has more information and is open to proposals.

I wrote up a proposal titled All you EVER wanted to know about client-side frameworks. I see a lot of FUD around client-side frameworks, and I want to talk about that. It’ll be about philosophy, patterns, best practices, code and helping developers make choices.

I already have 12 upvotes for my talk. I believe some are from my colleagues from Bang The Table who gave me very useful feedback on the topic. When I told my team what common questions would be answered by my talk, one of our front-end developers, who works mainly with Angular.js, exclaimed “Those are the exact questions I have!”. That’s validation right there, folks!

If selected, this will be my first conference talk, as well as my first talk with slides. I’m a live coding type of speaker. I love code, and understand that no amount of slides will replace showing the audience actual, working code. However, when I need to talk about philosophy and patterns, I recognize the importance of slides. I do promise I’ll keep them to a minimum!

Go, check out my proposal, and if you’d like me speaking on that topic, please click the ‘+1’ button to vote!

Beautiful DSLs in Ruby - the One Where It All Began

| Comments

At Bang The Table, I work on our flagship product EngagementHQ. Six months ago, I rewrote its entire reporting section, that provides valuable analytics for community managers.

One of the main goals I set for myself here was to split up the concerns – I wanted a set of modules that would provide standalone, testable methods which extract individual pieces of data from the database, and a nice DSL that wraps around them to generate a report.

A week later, each report had gone from an untestable spaghetti of ActiveRecord and Enumerables to this:

1
2
3
4
5
6
7
8
9
10
11
12
class Reports::UsersReport < Reports::BaseReport
  def generate
    report do
      registered do
        users          :users_count
        visits         :visits_count
        median         :visits_per_user_median
        data           :visits_per_user_counts_with_login
      end
    end
  end
end

This DSL generates a hash, with the keys being the methods called, and values are populated by the methods specified by the symbol.

At the Bangalore Ruby User Group meetup in May 2013, I presented a talk on writing DSLs for beginners. I always prefer a live coding session to one with slides, so that’s what I did – built a DSL right there. Deepak Kannan called me a “ballsy bastard” for that.