Sumak
Sumak

Reputation: 1061

What are => and : in Ruby?

When we're defining a Hash in Ruby, there's several syntax we can use:

# IRB Ruby 2.7.1 - Defining a Hash
my_hash = { 'string_transformed_into_symbol_1': 'value',
            "string_transformed_into_symbol_2": 'value',
            'string_1' => 'value',
            "string_2" => 'value',
            symbol_1: 'value',
            :symbol_2 => 'value' }

I was thinking that the arrow => was from Ruby 1.8 and was replaced by the colon :. Though, from the example above, we can see that it is not only a syntactic sugar: : transforms a key String into Symbol:

# IRB Ruby 2.7.1 - Outputing a Hash
my_hash
=> { :string_transformed_into_symbol_1 => "value",
     :string_transformed_into_symbol_2 => "value",
     "string_1" => "value",
     "string_2" => "value",
     :symbol_1 => "value",
     :symbol_2 => "value" }

From this question, mu is too short's great answer stated:

The JavaScript style (key: value) is only useful if all of your Hash keys are "simple" symbols (more or less something that matches /\A[a-z_]\w*\z/i [...] But you still need the hashrocket if your keys are not symbols.

This makes me consider : and => as methods (but I know I'm wrong). However, I couldn't find anything on the documentation about it.

Q: What exactly are : and => ? How could I learn more about them, and where are they defined in Ruby's source code ?

Upvotes: 4

Views: 747

Answers (2)

Todd A. Jacobs
Todd A. Jacobs

Reputation: 84413

Lexer/Parser Tokens

The symbols you're referencing aren't methods or operators, they are lexer/parser tokens used to interpret the syntax of your source code. The hashrocket is defined as the tASSOC association token, which is used to associate things such as key/value pairs or exception stack traces.

The colon has several uses in Ruby, but IIRC Ruby 2.x introduced the postfix colon as syntactic sugar for tASSOC when the left-hand side is a Symbol. I'm less sure about how the token is defined or parsed in complex cases—assoc is the most likely bet for this example—but for practical purposes you can simply think of a: 1 as semantically equivalent to :a => 1.

You can also use Ripper#sexp to examine your source code to see how the lines will be parsed by the interpreter. For example:

require 'ripper'

pp Ripper.sexp "{a: 1}"
[:program,
 [[:hash,
   [:assoclist_from_args,
    [[:assoc_new, [:@label, "a:", [1, 1]], [:@int, "1", [1, 4]]]]]]]]
#=> [:program, [[:hash, [:assoclist_from_args, [[:assoc_new, [:@label, "a:", [1, 1]], [:@int, "1", [1, 4]]]]]]]]

pp Ripper.sexp "{:a => 1}"
[:program,
 [[:hash,
   [:assoclist_from_args,
    [[:assoc_new,
      [:symbol_literal, [:symbol, [:@ident, "a", [1, 2]]]],
      [:@int, "1", [1, 7]]]]]]]]
#=> [:program, [[:hash, [:assoclist_from_args, [[:assoc_new, [:symbol_literal, [:symbol, [:@ident, "a", [1, 2]]]], [:@int, "1", [1, 7]]]]]]]]

In both cases, you can see that the S-expression is using the colon to build an "assoc_new" subexpression. For further drill-down, you'd have to refer to the Ruby source tree.

See Also

Upvotes: 4

Holger Just
Holger Just

Reputation: 55833

The : and => symbols are part of Ruby's language syntax, i.e. something way below the conceptual level of methods or objects.

In the language implementation, they are recognized by the parser. As such, the parser sees your source code, parses it and (in this case) creates objects based on the source code. Specific syntax elements result in various objects to be created, e.g. if you write 3.14 in your source code, a new Float object will be created. Similarly, the defined syntax for creating Hashes as recognized by Ruby's parser defines various options to describe Hashes in your source code, e.g.

{ :symbol => 'value' }
{ symbol: 'value' }
{ 'symbol': 'value' }

Each of those options will create the same hash, namely one with a symbol key and a string value.

The first syntax option was the only original syntax to define Hashes. The others were introduced later to give developers more options to define hashes in a more "natural" looking way.

Upvotes: 1

Related Questions