Eigenclass in ruby

To me, “Eigenclass” is a weird name. Here is the definition of “Eigenclass” from wikipedia:

A hidden class associated with each specific instance of another class.

“Eigen” is a Dutch word, which means “own” or “one’s own”. So “Eigenclass” means the class that class owned by the instance itself.

To open the eigenclass of the object, Ruby provide the following way:

Open Eigenclass
1
2
3
4
5
6
7
foo = Foo.new
class << foo
# do something with the eigenclass of foo
end

Since the in most cases, the purpose that we open a eigenclass is to define singleton methods on specific object. So Ruby provide an easy way to define the singleton method on specific instance:

Shorten saying
1
2
3
4
5
6
7
foo = Foo.new
def foo.some_method
# do something
end

Since “static method” or “class method” is actually the singleton method of a specific class. So this statement is usually used to declare the “class method”.

Besides this simpler statment, we also can open the eigenclass of the class to achieve the same result.
We can write this:

Open eigenclass of the class
1
2
3
4
5
6
7
8
9
10
11
class Foo
class << self
# define class methods
end
# define instance methods
end

Since we’re in the class block, so the “self” indicates the Foo class instance. So we can use class << self; end to open the eigenclass of the class.

How to solve key_read failed error in git push

I assigned a dedicated ssh key pair for github repos.
And I have associated the key pair with github correctly in ~/.ssh/config.
But each time when I try to access github repos via ssh, both read(such pull or fetch) or write(such as push), I will get a strange error:

key_read: uudecode [some SSH key code]
ssh-rsa [SSH key code]
failed

I tried a lot to fix the problem, and finally I solved the problem by delete the file ~/.ssh/known_hosts
I assume the problem might be caused that there is some invalid association cached in the file. So maybe you can solve the problem by removing the related entries instead of delete the whole file.

Space Pitfall in coffee-script

Coffee Script had fixed quite a lot of pitfalls in Javascript. But on another hand it also introduced some other pitfalls, the most common one is the space.

Space in function declaration

Read the following code:

Show Message:Coffee
1
2
3
4
show = message ->
console.log message
show "space pitfall"

This is a quite simple script, but it failed to run. And if you might also feel confused about the error message: “message is not defined”

What happened to the code? We indeed had declared the message as argument of function show. To reveal the answer, we should analyze the compiled javascript.
Here is the compiled code:

Show Message:JS
1
2
3
4
5
6
7
8
// Generated by CoffeeScript 1.3.1
var show;
show = message(function() {
return console.log(message);
});
showe("space pitfall");

Look the fun declaration, you will see it is not a function declaration as we want but a function call.
The reason is that we omitted the parentheses around the argument and we add a new space between message and ->. So the coffee-script compiler interpret message as a function call with a function as parameter.

Soltuion
To fix this problem, we can remove the space between message and -> to enforce coffee-script compiler interpret them as a whole.

Show Message:Fix
1
2
3
4
show = message->
console.log message
show "space pitfall"

Best Practise
To avoid this pitfall, my suggestion is never omit the parentheses around the arguments, even there is only one argument.
And also including the function call, even coffee-script allow to omit the parentheses. Since you won’t able to chain the method call if you omit the parentheses.
So never omit parentheses, unless you are very certain that there is no any ambiguity and you won’t use method chain.

The space in array index

Since coffee script doesn’t support the negative index. So we should use following code as negative index:

Last Hero:Coffee
1
2
3
heros = ["Egeal Eye", "XMen", "American Captain", "IronMan"]
lastHero = heros[heros -1]
console.log lastHero

This piece of code is also failed to run, and the error message is “property of object is not a function”.
Quite wield right?
Let’s see what is behind the scene, here is the compiled code:

Last Hero:JS
1
2
3
4
5
6
7
8
// Generated by CoffeeScript 1.3.1
var heros, lastHero;
heros = ["Egeal Eyr", "XMen", "American Captain", "IronMan"];
lastHero = heros[heros.length(-1)];
console.log(lastHero);

Same problem, heros.length -1 is interpreted as heros.length(-1) instead of heros.length -1.
To fix this problem, we should write the code in following way:

Last Hero:Fix1
1
2
3
heros = ["Egeal Eye", "XMen", "American Captain", "IronMan"]
lastHero = heros[heros - 1]
console.log lastHero

Or

Last Hero:Fix2
1
2
3
heros = ["Egeal Eye", "XMen", "American Captain", "IronMan"]
lastHero = heros[heros-1]
console.log lastHero

Both solution is try to enforce the compiler divid the component in correct way.

And unfortunately, there is no way to avoid this problem, the only thing you can do is always be aware the spaces in expression.

How to print multiple line string on bash

To display some pre-formatted text onto screen, we need the following 2 capabilities:

Construct Multiple Text

There are 2 ways to construct multiple line strings:

  • String literal

    String Literal
    1
    2
    3
    4
    5
    text = "
    First Line
    Second Line
    Third Line
    "
  • Use cat

    cat
    1
    2
    3
    4
    5
    6
    text = $(cat << EOF
    First Line
    Second Line
    Third Line
    EOF
    )

For some reason, echo command will eat all the line break in the text, so we should use printf instead of echo.
And printf supports back-slash-escape, so we can use \n to print a new-line on screen.

Dynamic Singleton Methods in Ruby

Today, I pair with Ma Wei to refactor a piece of pre-existed code. We try to eliminate some “static methods” (in fact, there is no real static method in ruby, I use this term to describe the methods that only depends on its parameters other than any instance variables).

The code is like this:

Recruiter.rb
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
class Recruiter
def approve! candidates
Candidate.transaction do
candidates.each do |candidate|
candidate.status.approve!
end
end
end
def reject! candidates
Candidate.transaction do
candidates.each do |candidate|
candidate.status.reject!
end
end
end
def revoke! candidates
Candidate.transaction do
candidates.each do |candidate|
candidate.status.revoke!
end
end
end
# ...
# Some other methods similar
end

As you can see the class Recruiter is used as a host for the methods that manipulate the array of candidates, which is a strong bad smell . So we decide to move these methods to their context class.

In Java or C#, the solution to this smell is quite obvious, which could be announced as “Standard Answers”:

  1. Mark all methods static.
  2. Create a new class named CandiateCollection.
  3. Change the type of candidates to CandidateCollection.
  4. Mark all methods non-static, and move it to CandidateCollection class.
    If you use Resharper or IntelliJ enterprise version, then the tool can even do this for you.

But in ruby world, or even in dynamic language world, we don’t like to create so many classes, especially these “strong-typed collection”. I wish I could inject these domain related methods to the array instance when necessary, which is known as “singleton methods” in ruby.
To achieve this, I might need the code like this:

Singleton Methods
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def wrap_array array
def array.approve!
# ...
end
def array.reject!
# ...
end
# ...
# Some other methods similar
array
end

With the help of this wrap_array method, we can dynamic inject the method into the array like this:

call wrap_array
1
wrap_array(Candidate.scoped_by_id(candidate_ids)).approve!

This is cool, but still not cool enough. We still have problems:

  1. All the business logic is included in the wrap method. It is hard to maintain.
  2. Where should we declare this wrap method? In class Array or another “static class”?

The answer to the 1st question is easy, our solution is encapsulate these logics into a module:

Module CandidateCollection
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
module CandidateCollection
def approve!
# ...
end
def reject!
# ...
end
def revoke!
# ...
end
# ...
# Some other methods similar
end
end

By encapsulate the logic into a module, then we can extract it into a single file, so the logic could be organized in the way as we want.
Now we need to solve the second problem and reuse the module we just created.

To achieve this, we wrote the following code:

Array.to_candidate_collection
1
2
3
4
5
6
7
8
class Array
def to_candidate_collection
class << self
include CandidateCollection
end
self
end
end

In the code, we re-opened the class Array, and define a new method called to_candidate_collection, which is used to inject domain methods into a generic array.
So we can have the following code:

Call to_candidate_collection
1
Candidate.scoped_by_id(candidate_ids).to_candidate_collection.approve!

Now our refactoring is basically completed.

But soon, we realize that is pattern is really powerful and should be able to be reused easily. So we decide to move on.
We want to_candiate_collection be more generic, so we can dynamically inject any module, not just CandidateCollection.
So we wrote the following code:

dynamic_inject
1
2
3
4
5
6
7
8
class Array
def dynamic_inject module
class << self
include module
end
self
end
end

So we can have the code like this:

call dynamic_inject
1
Candidate.scoped_by_id(candidate_ids).dynamic_inject(CandidateCollection).approve!

The code looks cool, but failed to run.
The reason is that we opened the meta class of the instance, which means we enter another level of context, so the parameter module is no longer visible.
To solve this problem, we need to flatten the context by using closure. So we modified the code as following:

dynamic_inject version 2
1
2
3
4
5
6
7
8
9
class Array
def dynamic_inject module
metaclass = class << self; self; end
metaclass.class_eval do
include module
end
self
end
end

The code metaclass = class << self; self; end is very tricky, we use this statement to get the meta class of the array instance.
Then we call class_eval on meta class, which then mixed-in the module we want.

Now the code is looked nice. We can dynamically inject any module into “Array” instance.
Wait a minute, why only “Array”? We’d like to have this capability on any object!
Ok, that’s easy, let’s move the method to Kernel module, which is mixed-in by Object class.

dynamic_inject version 3
1
2
3
4
5
6
7
8
9
module Kernel
def dynamic_inject module
metaclass = class << self; self; end
metaclass.class_eval do
include module
end
self
end
end

Now we can say the code looks beautiful.

NOTICE:
Have you noticed that we have a self expression at the end of the dynamic_inject method as return value.
This statement is quite important!
Since we will get “undefined method error” when calling Candidate.scoped_by_id(candidate_ids).dynamic_inject(CandidateCollection).approve! if we missed this statement.
We spent almost 1 hour to figure out this stupid mistake. It is really a stupid but expensive mistake!


Instead of these tricky ways, for Ruby 1.9+, it is okay to use extend method to replace the tricky code.
The extend method is the official way to do “dyanamic inject” as described before.

How to launch Mac OS Terminal as Interactive Shell rather than Log-in Shell

As described in previous post, Mac OS launch its terminal as Log-In shell rather than Interactive Shell, which is different to default behavior of Unix and Linux. As a result, Terminal will load “bash_profile” as its profile rather than the normal “bashrc”.

This unique behavior might cause some problem when you try to port CLI tool from Unix or Linux.
Because basically, the ported app infers that the bash_profile should be loaded only once, and only when user just logged in. But in Mac OS, this inference is wrong, which can cause some weird problem.

This default behavior sometimes is annoying, and in fact, this Mac OS Terminal’s “unique” behavior can be configured. And even more, you can use other shell program, such as ksh, rather than the default bash.

Mac user can customize this behavior in Terminal’s Preferences dialog of Terminal app.
Terminal Preferences Dialog

If you choose the command to launch bash, the launched shell will become a interactive shell, which will load .bashrc file rather than .bash_profile file.

Bash Profile on Mac OS X

In Linux and Unix world, there are 2 common used shell profiles: ~/.bashrc and ~/.bash_profile. These two profiles are usually used to initialize user bash environment, but there still are some slightly differences between them two.
According to bash manual, .bashrc is “interactive-shell startup file”, and .bash_profile is “login-shell startup file”.

What’s the difference between interactive-shell and login-shell

Basically, the login-shell means the shell opened when user log in via console. It could be the shell opened on local computer after you entered correct user name and password, or the shell opened when you ssh to a remote host.
So according to the bash_profile will be loaded only once, that’s right after you logged into a computer, either locally or remotely.

And, on the other hand, the interactive-shell could be more widely used, be seen more often. It is the shell opened after you logged in, such as the shell opened from KDE or Gnome.

Mac Terminal’s Pitfall

According to the manual, the Terminal App on Mac is the typical “interactive-shell”, so theoretically Terminal should load “.bashrc” to initialize the shell environment. But the fact is Terminal doesn’t load the “.bashrc”, instead it load “.bash_profile” for initialization.
So in a word, Mac’s Terminal doesn’t follow the routine strictly. We need to be aware it.

And not all the shell are interactive! If the shell is not interactive, the Terminal App won’t load the profile file to initialize the environment.
A typical non-interactive shell in the shell that TextMate used to run command script, which means in TextMate’s shell, these environment variables, path and even alias you used in you daily life might not be available for TextMate’s command.
And also the most hurt one, the rvm function also won’t be available in TextMate’s command shell, which means if you call rake or rails in TextMate’s command script, you are very possibly got error because it cannot find proper gem or other resources.
So you should always remember to source and run the “.bash_profile” file or setup these values once again.

exports vs module.exports in node.js

I was confused about how require function works in node.js for a long time. I found when I require a module, sometimes I can get the object I want, but sometimes, I don’t I just got an empty object, which give an imagination that we cannot export the object by assigning it to exports, but it seems somehow we can export a function by assignment.

Today, I re-read the document again, and I finally make clear that I misunderstood the “require” mechanism and how I did that.

I clearly remember this sentence in the doc

In particular module.exports is the same as the exports object.

So I believed that the exports is just a shortcut alias to module.exports, we can use one instead of another without worrying about the differences between them two.
But this understanding is proved to be wrong. exports and module.exports are different.

Today I found this in the doc:

The exports object is created by the Module system. Sometimes this is not acceptable, many want their module to be an instance of some class. To do this assign the desired export object to module.exports.

So it says that module.exports is different from exports. And it you exports something by assignment, you need to assign it to module.exports.

Let’s try to understand these sentences deeper by code examples.

In the saying

The exports object is created by the Module system.

The word “created by” actually means when node.js try to load a javascript file, before executing any line of code in your file, the module system executes the following code first for you:

1
var exports = module.exports

So the actual interface in node.js’s module system is module object. the actual exported object is module.exports not exports.
And the exports is just a normal variable, and there is not “magic” in it. So if you assign something to it, it is replaced absolutely.

That’s why I failed to get the exported object I want when I assign the it to exports variable.

So to export some variable as a whole, we should always assign it to module.exports.
And at same time, if there is no good excuse, we’d better to keep the convention that exports is the shortcut alias to module.exports. So we should also assign the module.exports to exports.

As a conclusion, to export something in node.js by assignment, we should always follow the following pattern:

1
2
3
exports = module.exports = {
...
}

Powershell script to serialize and deserialize hash-object to and from ini-like text

Powershell and .net fx provides a dozen of approaches to manipulate hash-object. And it is really easy and convenient to initialize hash-object with values from environment variables, registry or cli arguments.
And Hash-Object can be accessed and built into hierarchy easily, so to use powershell hash-object as deploy configuration is really powerful and convenient.

But in our system, the application uses the ini-like key-value pair plain text as the initial configuration file. So our deploy script need the ability to serialize and deserialize hash-object to and from ini-like config.

So I composed this piece of script.