Opal under a microscope: Object creation in Ruby and JavaScript

In this post we’ll learn how Ruby objects are mapped in JavaScript-land by the Opal compiler, how to call methods on them and how object instantiation works for both Ruby and JavaScript.

The basics: constants, methods and instance variables

The rule by which Ruby objects are compiled into JavaScript by Opal is quite simple. Constants are registered with their regular name under the window.Opal (i.e. the Opal property on the JavaScript window object). Methods are mapped to properties prefixed by a $ (dollar sign). Instance variables are just regular properties.

Example:

The following Ruby code:

class Foo
  def initialize
    @bar = 'BAR!'
  end

  def bar
    @bar
  end

  def baz
    'BAZ!'
  end
end

can be used from JavaScript in this way:

var Foo = Opal.Foo; // Constant lookup
obj = Foo.$new();   // calling method on class Foo

obj.bar             // accessing @bar      => 'BAR!
obj.$bar();         // another method call => 'BAR!'

obj.baz;            // a js property => undefined
obj.$baz();         // another method call => 'BAZ!'

As a Ruby developer you may be surprised that obj.baz returns undefined and not nil (actually window.Opal.nil) as that’s the value that you would expect to find while reading an instance variable for the first time.

What happens is that the Opal compiler will do just that, as long as you access those instance variables from Ruby code. In fact it statically analyzes the class’ code and pre-initializes to nil any instance variable for which it can find a reference.

Now that we have the basics let’s go further and put Foo.new under the microscope for both Opal and CRuby.

The birth of an object in 3 steps

By looking in detail how object instantiation is done in JavaScript by the Opal compiled code we’ll have a chance to learn how it actually works in CRuby.

The implementation of .new

At the cost of oversimplifying here’s the rough implementation of the #new method available to all classes in Ruby:

class Class
  def new(*args, &block)
    obj = allocate # allocates the memory in CRuby
    obj.send(:initialize, *args, &block) # forwards all arguments to #initialize
    return obj
  end
end

Breaking it down we see that:

  1. it calls #allocate in order to setup a raw object (in C it will also allocate the necessary memory)
  2. it forwards all arguments and block to #initialize
  3. it returns the object

Here’s how it looks in Opal (the code inside %x{} is JavaScript):

class Class
  def new(*args, &block)
    %x{
      var obj = self.$allocate();
      obj.$initialize.$$p = block;
      obj.$initialize.apply(obj, args);
      return obj;
    }
  end
end

(Class#new source)

As you can see the the only notable difference is in how the block is passed. Opal will store any block call on the method itself under the $$p property. This way blocks can’t be confused with regular arguments. Apart from that it’s clear that it’s fundamentally the same code.

Uncovering Class#allocate

The curious reader at this point is wondering what the allocate method does in JavaScript because surely it can’t manage memory. Let’s see the implementation:

class Class
  def allocate
    %x{
      var obj = new self.$$alloc;
      obj.$$id = Opal.uid();
      return obj;
    }
  end
end

(Class#allocate source)

Let’s break it down by line, but this time we’ll go in reverse order:

  1. The last line is the easiest one in which the code just returns the object: return obj.
  2. The middle one is still quite clear and seems to just assign a unique identifier to the object. That value will be the one returned by #object_id.
  3. The first and most important one is where stuff actually happens. The JavaScript new keyword is used to create an object whose constructor seem to be stored in $$alloc.

For those not very familiar with JavaScript I’ll show how objects are usually created:

// this function acts as the MyClass constructor
function MyClass() { this.foo = 'bar'; }

var obj = new MyClass;
obj.foo         // => 'bar'
obj.constructor // => MyClass

The awesome thing to me is that Opal manages to have an implementation that is really idiomatic in both Ruby and JavaScript.

3 Tricks to debug Opal code from your browser

1. Use pp

pp stands for Pretty Print and is part of the CRuby standard library. Usually what it does is just reformatting your output to make it readable.

require 'pp'
pp 10.times.map { 'hello' }

In CRuby would output:

["hello",
 "hello",
 "hello",
 "hello",
 "hello",
 "hello",
 "hello",
 "hello",
 "hello",
 "hello"]

Opal instead will just pass the object to console.log():

console.log output in Safari's console

2. Call Ruby methods from the browser console

Another good thing to keep in mind is how methods are mapped into JavaScript, the rule is really simple: $ is prefixed to the method name.

> Opal.top.$puts('hello world');
=> "hello world"

> Opal.Object.$new().$object_id();
=> 123

Once you know that, you can also learn how to call methods with and without blocks:

> Opal.send(Opal.top, 'puts', 'hello world');
=> "hello world"

> var object = Opal.send(Object, 'new');
> Opal.send(object, 'object_id');
=> 123

> Opal.block_send([1,2,3], 'map', function(n) { return n*2 });
=> [2,4,6]

> Opal.block_send([1,2,3], 'map', function(n) { return Opal.send(n, '*', 2); });
=> [2,4,6]

3. Inspecting instance variables

Last but not least remember that instance variables are mapped to simple unprefixed properties of the JavaScript object.

Opal code:

class Person
  def initialize(name)
    @name = name
  end
end

In the console (with JavaScript):

> var person = Opal.Person.$new('Pippo');
=> #<Person:123 @name="Pippo">

> person.name
=> "Pippo"

Conclusion

That’s all for now, happy hacking!

Simple Git HTTP server

The other day I had to share a repo to a colleague without him having access to the online repo.

Conscious that git can serve repositories through HTTP I set myself to discover the simplest way to do it without a full blown git hosting app like GitLab or Gitorious.

At that point I took out my google-fu and came up with the following:

git update-server-info # this will prepare your repo to be served
ruby -run -ehttpd -- . -p 5000
git clone http://localhost:5000/.git repo_name

Now by just knowing your IP anyone will be able to clone that repo.

BONUS

If you’re a PHP nostalgic OSX 10.10 comes with the php command which is able to serve a directory and interpret any PHP file in it (like mod_php would):

git update-server-info # this will prepare your repo to be served
php -S 0.0.0.0:5000 -t .
git clone http://localhost:5000/.git repo_name

Stay tuned for more PHP and Ruby awesomeness!

Using spring with pow!

The other day I was a bit sad for I was aware that pow (the web server) wasn’t leveraging spring (the Rails preloader) with its fast load times.

Fixing config.ru

Luckily this deficiency is easily fixed by adding the spring snippet to your config.ru:

# This file is used by Rack-based servers to start the application.

begin
  load File.expand_path('../bin/spring', __FILE__)
rescue LoadError
end

require ::File.expand_path('../config/environment',  __FILE__)
run Rails.application

Why JSON sucks for user configuration

In the current era of JavaScript JSON has become super common. In this article I want to make a point about it not being suitable for user configuration.

The good

Let’s start with the good parts. It’s not XML. Being born as a data interchange format from the mind of Douglas Crockford it shines for its simplicity in both the definition and easiness in parsing. That’s pretty much it. As a configuration tool the only good thing I can say is that many people are accustomed to it, and usually already know its rules.

The bad

As popular as it is the JSON format has started to be overused, especially for letting users to configure stuff (that’s the point of the article). The first thing to notice here is that JSON is not intended to be used that way, instead we can quote from the official page:

JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write. It is easy for machines to parse and generate.

source: http://json.org

What I’d like to highlight is that JSON is a compromise between write/readability for both humans and machines. A data interchange format can easily be almost unreadable to humans, that happens all the time with binary formats but a configuration format should instead be biased towards humans.

The ugly

But what’s wrong with JSON?

I see three things that make JSON fail as a configuration format:

Strictness

The format is really demanding. Contrary to the ordinary JavaScript literal object format (which is where it comes from) JSON mandates double quotes around keys and strict absence of commas before closed parentheses.

Lack of comments

The absence of comments is perfectly fine in a data interchange formats where the payload will probably travel on wires and needs to be as tiny as possible. In a configuration format conversely it’s plain non-sense as they can be used to help the user explaining each configuration option or for the user to explain why he chose a particular option.

Readability

While JSON is quite readable when properly formatted, this good practice is not enforced by the format itself, so it’s up to coders good will to add returns, tabs and spaces in the right places. Lucky enough they usually do.

Conclusions

JSON has become very popular thanks to JavaScript to the point that is also a super common format for user configuration. It wasn’t designed to do so and in fact it does an awful job.

Almost anything is a good alternative, from INI to CSON. The one I like the most tho is YAML (which in turn has been erroneously used as a data interchange format). Here is the YAML tagline:

YAML is a human friendly data serialization standard for all programming languages.

source: http://yaml.org

Dead simple view layer with Opal and jQuery

Dead simple view layer with Opal and jQuery

Lately I noticed that I started to port from project to project a simple class that implements a basic view layer with Opal and jQuery.

In this post we will rebuild it from scratch, you can consider it as an introduction for both Opal and Ruby, and maybe also a bit of OOP

The View class

If you still generate your HTML on the server (making happy search engines) and progressively add functionality via CSS and JavaScript then this class is probably a good fit.

Let’s start by defining our API. We want an object that:

  • takes charge of a piece of HTML
  • can setup listeners and handlers for events on that HTML node
  • can be easily composed with other objects
  • exposes behavior, hiding implementation

Step 1: An object, representing a piece of HTML

Say we have this HTML, representing a search bar:

<section class="search">
  <form>
    <input type="search" placeholder="Type here"></input>
    <input type="submit" value="Search">
  </form>
</section>

This is how we want to instantiate our view:

Document.ready? do
  element = Element.find('section.search')
  search_bar = SearchBar.new(element)
  search_bar.setup
end

The SearchBar class can look like this:

class SearchBar
  def initialize(element)
    @element = element
  end

  attr_reader :element

  def setup
    # do your thing here…
  end
end

Step 2: Adding behavior

Now that we have a place let’s add some behavior. For example we want to clear the field if the ESC key is pressed and to block the submission if the field is empty. We need to concentrate on the #setup method.

feature 1: “clear the field on ESC”

class SearchBar
  # …

  ESC_KEY = 27

  def setup
    element.on :keypress do |event|
      clear if event.key_code == ESC_KEY
    end
  end


  private

  def clear
    input.value = ''
  end

  def input
    @input ||= element.find('input')
  end
end

As you may have noted we’re memoizing #input and we’re searching the element inside our current HTML subtree. The latter is quite important, especially if you’re coming from jQuery and used to $-search everything every time. Sticking to this convention will avoid down the road those nasty bugs caused by selector ambiguities.

feature 2: “prevent submit if the field’s empty”

class SearchBar
  # …

  def setup
    element.on :keypress do |event|
      clear if event.key_code == ESC_KEY
    end

    form.on :submit do |event|
      event.prevent_default if input.value.empty?
    end
  end


  private

  def form
    @form ||= element.find('form')
  end
end

YAY! Sounds like we’re almost done!

Step 3: Extracting the View class

Now seems a good time to extract our view layer, thus leaving the SearchBar class with just the business logic:

class View
  def initialize(element)
    @element = element
  end

  attr_reader :element

  def setup
    # noop, implementation in subclasses
  end
end


class SearchBar < View
  def setup
    # …
  end

  private

  # …
end

Step 4: Topping with some “Usability”

Now that the View class has come to life we can add some sugar to make out lives easier.

Default Selector

We already know that the class will always stick to some specific HTML and its selector, it’s a good thing then to have some sensible defaults while still allowing to customize. We’ll define a default selector at the class definition, this way:

class SearchBar < View
  self.selector = 'section.search'
end

Document.ready? { SearchBar.new.setup }

The implementation looks like this:

class View
  class << self
    attr_accessor :selector
  end

  def initialize(options)
    parent   = options[:parent] || Element
    @element = options[:element] || parent.find(self.class.selector)
  end
end

ActiveRecord style creation

I’d also like to get rid of that Document.ready? that pops up every time. As always let’s define the API first:

class SearchBar < View
  self.selector = 'section.search'
end

SearchBar.create

And then the implementation

class View
  # …

  def self.create(*args)
    Document.ready? { create!(*args) }
    nil
  end

  def self.create!(*args)
    instance = new(*args)
    if instance.exist?
      instances << instance
      instance.setup
    end
    instance
  end

  def exist?
    element.any?
  end

  def self.instances
    @instances ||= []
  end
end

While there we also added a check on element existence and a list of active instances so that we can play nice with JS garbage collection and instantiate the class even if the HTML it needs is missing (e.g. we’re on a different page).

Conclusion

Hope you enjoyed and maybe learned a couple of things about Opal and opal-jquery, below are some links for you:

The full implementation is available in this gist: https://gist.github.com/elia/50a723e6133a645b4858

Opal’s website: http://opalrb.org
Opal API documentation: http://opalrb.org/docs/api
Opal-jQuery API documentation: http://opal.github.io/opal-jquery/doc/master/api
jQuery documentation: http://jqapi.com (unofficial but handy)
Vienna, a complete MVC framework: https://github.com/opal/vienna (unofficial but handy)

3 Simple examples from Ruby to Elixir

In this post we’re gonna see how to transform a simple script from Ruby to Elixir.

Installing Elixir

The first thing you need is to have Elixir installed on your box, the instructions are dead simple and you can
find them in the official Getting Started page.
For example on OS X is as simple as brew update; brew install elixir.

The Ruby Script

The script is the one I use to fire up my editor adding support for the file:line:column
format that is often found in error stacktraces. I keep this script in ~/bin/e.

#!/usr/bin/env ruby

command = ['mate']

if ARGV.first
  file, line_and_column = ARGV.first.split(':', 2)

  command << file
  command += ['-l', line_and_column] if line_and_column
end
command << '.' if command.size == 1
exec *command

Take 1: Imperative Elixir

As we all know, no matter the language, you can keep your old style. In this first example we’ll see the same

#!/usr/bin/env elixir

if System.argv != [] do
  [file| line_and_column] = String.split(hd(System.argv), ":", parts: 2)
  args = [file]

  if line_and_column != [] do
    args = args ++ ["-l"| line_and_column]
  end
else
  args = ["."]
end
System.cmd("mate", args)

The “Guillotine” operator

The first thing we notice the change in syntax for the splat assignment:

# Ruby
a, b = [1,2,3]
a # => 1
b # => 2
<pre><code class="elixir"># Elixir

[a| b] = [1,2,3]
a # => 1
b # => [2,3]

The | operator in Elixir will in fact take out the head of the list and leave the rest on its right.
It can be used multiple times:

[a| [b| c]] = [1,2,3]
a # => 1
b # => 2
c # => [3]

what happens here is that the list that in the first example was b is now beheaded again.
If instead we wanted c to equal 3 the assignment would look like this:

[a| [b| [c]]] = [1,2,3]
a # => 1
b # => 2
c # => 3

As we can see Elixir matches the form of the two sides of the assignments and extracts values and variables accordingly.

Other notes

Let’s see a couple of other things that we can learn in this simple example

List concatenation: ++

The ++ operator simply concatenates two lists:

a = [1,2] ++ [3,4]
a # => [1,2,3,4]

Double quoted "strings"

All strings need to be double quoted in Elixir, as single quotes are reserved for other uses.
I make the mistake of using single quotes all the time. Probably that’s the price for being a
ROFLScale expert.

Take 2: First steps in Pattern Matching

With this second version we’re gonna see the pattern matched case.

Notice anything?

Yes. All ifs are gone.

#!/usr/bin/env elixir

args = System.argv
args = case args do
  [] -> []
  [""] -> []
  [path] -> String.split(path, ":", parts: 2)
end

args = case args do
  [] -> ["."]
  [file] -> [file]
  [file, ""] -> [file]
  [file, line_and_column] -> [file, "-l", line_and_column]
end

System.cmd("mate", args)

We now reduced the whole program to a couple of switches that will route the input and transform it
towards the intended result.

That’s it. No highlights for this implementation. Just a LOLCAT.

cat getting scared for no reason

Take 3: Modules and pipes

<pre><code class="elixir">#!/usr/bin/env elixir

defmodule Mate do
def open(argv), do: System.cmd(“mate”, argv |> parse_argv)

def parse_argv([]), do: [“.”]
def parse_argv([options]) do
[file| line_and_column] = String.split(options, “:”, parts: 2)
[file| line_and_column |> line_option]
end

def line_option([]), do: []
def line_option([“”]), do: []
def line_option([line_and_column]), do: [“-l”, line_and_column]
end

Mate.open System.argv

Module and defs

As you have seen we have now organized out code into a module and moved stuff to defined module
functions. The same function can be defined multiple times, Elixir will take care of matching the arguments
you pass to a function to the right.

Let’s review the two forms of function definition:

defmodule Greetings do
  # extended
  def hello(name) do
    IO.inspect("hello #{name}")
  end

  # onliner
  def hello(), do: IO.inspect("hello world!")
end

Greetings.hello "ppl" # => "hello ppl"
Greetings.hello       # => "hello world!"

Be sure to remember the comma before do: otherwise Elixir will complaint.

The |> pipe operator

If you’re familiar with commandline piping you’ll fell like at home with the pipe operator.
Basically it will take the result of each expression and pass it as the first argument of the next one.

Let’s see an example:

"hello world" |> String.capitalize |> IO.inspect # => "Hello world"

That is just the same of:

s = "hello world"
s = String.capitalize(s)
s = IO.inspect(s)
s # => "Hello world"

or

IO.inspect(String.capitalize("hello world")) # => "Hello world"

Where the latter is probably the least comprehensible to human eyes

What’s next?

Playing

Studying

Watching

NTML authentication for Rails from inside Microsoft™ ActiveDirectory

I ended up with a decent setup in which the whole authentication is handled by IIS on a Windows machine that lives inside the ActiveDirectory tree. Adapting from these instructions.

IIS will act as a reverse proxy to your Rails app (typically installed on a *nix server, apache+passenger in my case).

The secret resides in configuring IIS to handle NTLM and then adding this nifty plugin that will basically reproduce the mod_proxy api for IIS.

Here’s an iirf.ini example:

# NOTE: 
# This file should be placed in the IIS document root 
# for the application

StatusInquiry ON
RewriteLogLevel 3
RewriteLog ....TEMPiirf
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^.*$ - [L]
ProxyPass ^/(.*)$ http://1.2.3.4:80/$1
ProxyPassReverse / http://1.2.3.4/

With this setup you can rely on the fact that the authentication is performed by IIS and you only get authenticated request with the authentication information stored inside HTTP_AUTHORIZATION.

To parse the user data from the auth header I used net-ntlm:

require 'kconv'
require 'net/ntlm'

if /^(NTLM|Negotiate) (.+)/ =~ env["HTTP_AUTHORIZATION"]
  encoded_message = $2
  message = Net::NTLM::Message.decode64(encoded_message)
  user = Net::NTLM::decode_utf16le(message.user)
end

After that you can even connect to the LDAP ActiveDirectory interface and fetch details about the user.