Question

I am looking for an explanation for what's going on at the top of artoo.io robots. There is a declaration at the top of this example using the keyboard driver:

require 'artoo'

connection :keyboard, adaptor: :keyboard
device :keyboard, driver: :keyboard, connection: :keyboard

It seems that some shorthand/alternative syntax is displayed, and I'd love an explanation of that shorthand. I understand the alternative hash syntax: :adapter => :keyboard.

What is going on in those last two lines of code above? What is connection? Is it a class inside artoo that is being initialized? Why is there no new? Where does :keyboard come from? If there is an alternative syntax that represents the relationships more explicitly, could you show that as well?

Was it helpful?

Solution

This is a great question. It might be a duplicate but I couldn't find one and this is the sort of thing that is tricky for smart programmers who are new to Ruby.

First, to your question: What is connection?

It is a method call. In some cases it can be hard to tell what is a method and what is a variable, because it just depends on how they were defined. But in this case it is clear because connection has parameters after it. In ruby, a method can be called like this:

foo

In that case it is a method that takes no parameters. Or it can look like this:

foo 1, 2, 3

That is a method with three parameters. Or it can look like this:

foo(1, 2, 3)

That is the same method, but with a slightly different syntax (which is more familiar to people experiences in c-mimicing languages like c, C++, Java, Javascript, C#, etc...)

So when you see parameters listed after a bare word, with no operators between, it is a sure sign it's a method call.

Now to break down your code entirely.

require 'artoo'

This is technically a method call. You're calling the require method and passing a single parameter of the literal string 'artoo'. As you probably know, require loads an external ruby file into the current file.

connection :keyboard, adaptor: :keyboard

This is a method call with some syntactic sugar:

You know right away that connection is a method call because it has parameters after it (i.e. no operator between connection and what comes after). But what parameters?

:keyboard: is a Symbol, which is ruby's equivalent of an intern'd string.

adaptor: :keyboard is a Hash.

Ruby has two primary hash syntaxes:

{key => value}

Where key and value are any objects, or:

{key: value}

Where key is a bare literal Symbol and value is any object. Also, to keep code clean, when you pass a Hash as the last parameter to a method, you can leave off the { and } because it is unambiguous. It ends up giving you a clean "named parameter" style method call:

do_something_to my_person, kindness: 10, aggressiveness: 2

In your code:

connection :keyboard, adaptor: :keyboard

You have the alternate hash syntax (symbol keys) with the { and } left off. The whole line is 100% equivalent to:

connection(:keyboard, {:adaptor => :keyboard})

Your last line:

device :keyboard, driver: :keyboard, connection: :keyboard

Is the same thing. Equivalent to:

device(:keyboard, {:driver => :keyboard, :connection => :keyboard})

It just looks nicer (once you get used to it).

OTHER TIPS

In your example, connection and device are methods. The adapter: :keyboard, driver: :keyboard and :connection: :keyboard bits are parameters being passed as a hash to those methods. The first parameters passed to connection() and device() are not being passed in a hash.

The same code could be rewritten like this:

connection :keyboard, { adaptor => :keyboard }
device :keyboard, { driver => :keyboard, connection => :keyboard }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top