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?
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).