Reflections of a Sunsneezer

Medium-sized, Unsatisfying Tidbits of Ruby

Blocks In-depth: instance_eval —

instance_eval is a BasicObject method that takes in a block and calls the block with the receiver as self. You can use instance_eval to do anything you’d like from within the scope of any object.

A very common usage for this trick is for configuring options by using a Clean Room. A Clean Room is an blank object with some helper methods that allows your users to call methods on it as if they were opening the class:

instance_eval provides 1 parameter to the block it calls, and that parameter is the receiver. So in this example, inside the configure block we get the ‘config’ parameter which is equal to ‘self’.

You can take this example a step further and start progressing to a DSL for configuring your library by implementing a few mimic methods in the Configuration class:

Now that’s more like it!


Blocks In-depth: Lambdas —

Procs have two types of semantics – yield semantics and invocation semantics. Procs with yield semantics are the Procs created by Proc#new (or Kernel#proc) and Procs with invocation semantics are the ones created by the lambda method.

Yield semantics are the one you know and love from blocks – they ignore extra arguments and default missing arguments to nil:

Also, calling ‘return’ inside blocks with yield semantics will return from the creation site:

Blocks with invocation semantics behave a bit differently – they raise exceptions on extra arguments and missing arguments:

Also, calling ‘return’ inside the blocks with invocation semantic will return from within the block:

If typing ‘lambda’ is too much for you, you can simply use the stabby operator:


Blocks In-depth: Procs —

You’ve probably heard that “everything in Ruby is an object”. Well, that’s a lie – blocks aren’t objects. The only way you can create a block is by attaching it to a method call and you can’t save a reference to a block. That’s what you have Procs for.

A proc (an instance of the Proc class) is a block wrapped in an object. Proc#initialize accepts a single parameter – a block, and keeps that block as part of the Proc instance. When you want to call the block, you simply invoke the ‘call’ method on the Proc and provide whatever parameters you need.

Remember we said blocks can only be created by providing them as arguments to a method call? Well, this is exactly what happens here. A block is passed to Proc#new and kept inside of that Proc instance.

A synonym to Proc#new is Kernel#proc. There are also some alternative ways to call Proc objects. The following example does exactly the same as the previous one, but in 3 different versions:

There are some reasons for having these alternate methods, but I suggest you stick to Proc#call which expresses the intent clearly.

Having the ability to keep blocks inside of variables is super powerful. It allows you to store references to operations and perform them at any given time. You can accept a Proc in a method’s parameters list and keep it for future use:

Blocks In-depth: Scope —

At every step along the execution path of your program you have a different set of binding, self and constants. You can refer to that as your current scope. If two methods exist in the same scope, they can access the same variables:

In this example, ‘initialize’ and ‘bar’ share the same scope (which is Foo’s scope), so they can both access ‘@hello’.

There are 2 scenarios in which scopes change: when you enter a class/module definition and when you enter a method definition. These are called Scope Gates. Once you enter a class/module you enter a new scope, so variables that were defined in the previous scope are unavailable to you. Same goes for method definitions. For example:

There are ways to bypass this though. You can define class/module and method with a block (thus bypassing the ‘class’, ‘module’ or ‘def’ keywords) and keep the same scope.


Blocks In-depth: Closures —

In the previous post, we saw that every method can accept a block and execute it using the ‘yield’ command, but what’s really a block? As far as we know, up until now, a block is just a piece of code, but the only way it can be useful is with some data to act as its context. This is known as the block’s binding. At any given point of your program’s runtime, you can call the ‘binding’ kernel method, which will return a new Binding object with the current context.

You can explore bindings by providing them to Kernel#eval:

Notice that ‘puts_x’ suddenly has access to x, which is not available inside it’s scope. Going back to blocks – blocks carry along the bindings that were present during the time they were created:

In this example, even though the block is called inside the ‘greet’ method (which we’ll refer to as the block’s call site), it has access to the ‘name’ variable in the main program (which we’ll refer to as the block’s creation site).

The combination of a set of instructions (code) and an environment of variables (context) is known as a closure. Looking at what we’ve learned about blocks so far, we now understand that blocks are closures, as they are a set of instructions (the code inside the block), and they have an environment of variables (their binding) which they carry along from their creation site.


Blocks In-depth: do…end Vs. Curly Brackets —

You can define blocks with do…end or by using curly brackets. There are two common conventions that help you decide whether to use do…end or curly brackets:

  1. Single / multi line – use do…end for multiline blocks; Use curly brackets for single line blocks.
  2. The Weirich convention – use curly brackets for blocks that return values that are significant; Use do…end for blocks that don’t explicitly return values, but rather cause some sort of side effect.

There’s no right or wrong way of doing this. Different teams have their own guideline for this.

Personally, I try to follow the Weirich convention as much as I can, but sometimes I stick with do…end, especially when things start to look Javaish due to extensive use of curly brackets.


Blocks In-depth: Calling Blocks —

This is part 1 of a series of short blog posts I plan to write on blocks in Ruby. In this blog post series I’ll go back to the basics and cover them as if I’m introducing the subject, but if you’ve been around the Ruby scene for a while, you probably know most of the material covered here. Hopefully advanced readers could also find some interesting bits as well.

Blocks are all around us in Ruby, and you’ve probably been using them since you got started with Ruby. The most common use you probably know for blocks is with Enumerable, and particularly the ‘each’ method. However, blocks can do much more then iterate over collections. They can also be useful for pre & post operations, deferred evaluation of code and for building Domain Specific Languages.

Supplying a block to a method is easy – you simply call the method and place the content of your block within a do…end clause as follows:

Every method takes in a block, you don’t even have to specify it, but you do have to make sure that block gets run. You do this with the yield keyword, as follows:

Since you don’t have to specify a block as part of a method’s parameter list, your way of figuring out if a block was provided is by using the block_given? method. In the following example, if no block is passed to the log method, it won’t puts any text:

Remember that everything in Ruby is an object? Well, forget that! Blocks aren’t objects. You cannot keep references to blocks and you can’t assign them to variables. In fact, the only way you can create a block is by supplying it to a method. More on that in a later post.


assertion.should be_related_to_description —

When you are writing positive specs, use positive assertions. When you are writing negative specs, use negative assertions. This might sound trivial, but a lot of people are missing out on this.

Let’s look at a simple example. This simple User class has a method called ‘visit’, and a counter for unique visited attractions.

We want to verify that visiting a new attraction increases the visited attractions count, but multiple visits to the same place does not increase the count.

The problem is here subtle. The second spec is negative (it ”doesn’t increase…”), but the assertion is positive. A better way to write this would be:

Why is this better? It might look the same when you are writing the spec, but when the spec breakes and you want to understand what went wrong, I find it easier to know that what I see in the name of the spec is not happening, instead of doing a double not operator in my head.

This is quite similar to the “it ‘should foo‘” vs. “it ‘foos‘” debate – again, I find it easier to look at spec names and see what happens, instead of what should happen.


Time to get back to blogging! —

It’s been a long long time since I’ve blogged. In fact, I haven’t blogged at all since I moved from .NET to Ruby.

Given that I am so swamped with work right now, finding the time to blog is so implausible that it just might work. Stay tuned.

Oh, and if you’re looking for my old blog, don’t. But here it is anyway.