Semantics Def

October 22, 2015 – 12:56 am

Ruby's Implementation Does Not Define its Semantics

When I was first getting started with Ruby, I heard a lot of talk about blocks, and how you could "cast" them to Procs by using the & operator when calling methods. Last week, in comments about my last post (Ruby is NOT a Callable Oriented Language (It’s Object Oriented)), I heard that claim again.

To be honest, I never really thought that much about it, and the idea of "casting" a block to a Proc never took hold in my mental model, but when discussing my post with a number of people, I realized that a lot of people have this concept in their mental model of Ruby.

It is not part of Ruby's semantics.

In some cases, Ruby's internal implementation performs optimizations by eliminating the creation of objects until you specifically ask for them. Those optimizations are completely invisible, and again, not part of Ruby's semantics.

Here, I have three methods using blocks in different ways. In the first method (foo), I don't specify the block at all, yielding to the implicit block. In the second case, I specify a block parameter, print its objectid, and then send it on to the baz method. In the third case, I specify the block, print out its objectid and yield to the block.

In Ruby's semantics, these three uses are identical. In the first case, yield calls an implicit Proc object. In the second case, it takes an explicit Proc, then sends it on to the next method. In the last case, it takes an explicit Proc, but yields to the implicit copy of the same object.

So what's the & thing for?

In Ruby, in addition to normal arguments, methods can receive a Proc in a special slot. All methods can receive such an argument, and Procs passed in that slot are silently ignored if not yielded to:

def foo puts "HELLO" end foo { something_crazy } #=> "HELLO"

On the other hand, if you want a method to receive a Proc in that slot, and thus be able to yield to it, you specify that by prefixing it with an &:

def foo yield end my_proc = Proc.new { puts "HELLO" } foo(&my_proc)

Here, you're telling the foo method that my_proc is not a normal argument; it should be placed into the proc slot and made available to yield.

There are an awful lot of things in this country that I think would be...

It's Interesting...

William Snyder is an Associate Professor and Head of the Linguistics Department at the University of Connecticut. Since 2003 he has been co-editor of Language Acquisition: A Journal of Developmental Linguistics. He is also the author of more than fifty publications on children's acquisition of syntax, semantics, phonology, and morphology. His...

Twitter Activity

@mbindwane @WaylanderMR @maggsnaidu @alpheusb @De_Imperial silly semantics can change the meaning of a sentence. Unsure you have law degree?
Wed, 24 June 2015 11:33 AM