What's the Difference Between Colon ":" and Fat Arrow "=>"

What's the difference between colon : and fat arrow =

The syntax is for defining Hash key/value pairs, and the difference depends on the Ruby version.

Supported in both Ruby 1.8 and Ruby 1.9

:foo => true

Supported only in Ruby 1.9

foo: true

If you're developing in Ruby 1.9 you should probably use the syntax:

foo: true

as it appears to be the direction the community is moving in.

Flutter/Dart - Difference between () {} and () = {}

The fat arrow syntax is simply a short hand for returning an expression and is similar to (){ return expression; }.

According to the docs.

Note: Only an expression—not a statement—can appear between the arrow (=>) and the semicolon (;). For example, you can’t put an if statement there, but you can use a conditional expression

void main(){
final cls = TestClass();
cls.displayAnInt((){
//you can create statements here and then return a value
int num1 = 55;
int num2 = 1;
int sum = num1 + num2;
return sum;
});
cls.displayAnInt(() => 55 + 1); // simply return an int expression
}
class TestClass{

displayAnInt(makeIntFunc){

int intValue = makeIntFunc();
print('The int value is $intValue');
}
}

From the code above, You can see that multiline statement can be made when the callback function is used and then a value is returned, while the fat arrow simply has an expression with no return keyword.

Considering your answer about fat arrows not supporting multiline statements in dart. This is quite understandable since doing () => {somtheing} would imply you are returning a map and it would expect to see something like () => {'name':'John', 'age':25} and not () => { _myTxt = "Text Changed";_myTxt = "Never Mind"; } .

Map with fat arrow vs colon (Poison - json decode)

ab = %{a: 1} # atom key you can access it like ab.a
ac = %{"a" => 1} # string key you can access it ac["a"]

Poison.decode! return format #2:

Data which comes from outside your application, broadly speaking, can’t be trusted. Given that atom allocation can lead to memory exhaustion in a long-running Erlang system, using atoms for external data opens up your app for a potential denial of service (DoS) attack.

This fact is reflected in many Elixir libraries, for example the popular JSON parser Poison. Well-behaved libraries will generally use strings as map keys when converting external data into an internal data structure

If you want to convert map keys from string to atom.You can do:

iex> maps = %{"foo" => "bar"}
%{"foo" => "bar"}
iex> for {key, val} <- maps, into: %{}, do: {String.to_atom(key), val}
%{foo: "bar"}

Is there any difference between the `:key = value ` and `key: value ` hash notations?

Yes, there is a difference. These are legal:

h = { :$in => array }
h = { :'a.b' => 'c' }
h[:s] = 42

but these are not:

h = { $in: array }
h = { 'a.b': 'c' } # but this is okay in Ruby2.2+
h[s:] = 42

You can also use anything as a key with => so you can do this:

h = { C.new => 11 }
h = { 23 => 'pancakes house?' }

but you can't do this:

h = { C.new: 11 }
h = { 23: 'pancakes house?' }

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, AFAIK the parser uses its label pattern for these keys).

The :$in style symbols show up a fair bit when using MongoDB so you'll end up mixing Hash styles if you use MongoDB. And, if you ever work with specific keys of Hashes (h[:k]) rather than just whole hashes (h = { ... }), you'll still have to use the colon-first style for symbols; you'll also have to use the leading-colon style for symbols that you use outside of Hashes. I prefer to be consistent so I don't bother with the JavaScript style at all.

Some of the problems with the JavaScript-style have been fixed in Ruby 2.2. You can now use quotes if you have symbols that aren't valid labels, for example:

h = { 'where is': 'pancakes house?', '$set': { a: 11 } }

But you still need the hashrocket if your keys are not symbols.

Supporting Ruby 1.9's hash syntax in Ruby 1.8

I think you're out of luck, if you want to support 1.8 then you have to use =>. As usual, I will mention that you must use => in certain cases in 1.9:

  1. If the key is not a symbol. Remember that any object (symbols, strings, classes, floats, ...) can be a key in a Ruby Hash.
  2. If you need a symbol that you'd quote: :'this.that'.
  3. If you use MongoDB for pretty much anything you'll be using things like :$set => hash but $set: hash is a syntax error.

Back to our regularly scheduled programming.

Why do I say that you're out of luck? The Hash literal syntaxes (both of them) are hard-wired in the parser and I don't think you're going to have much luck patching the parser from your gem. Ruby 1.8.7's parse.y has this to say:

assoc    : arg_value tASSOC arg_value
{
$$ = list_append(NEW_LIST($1), $3);
}
;

and tASSOC is => so hash literals are hard-wired to use =>. 1.9.3's says this:

assoc    : arg_value tASSOC arg_value
{
/*%%%*/
$$ = list_append(NEW_LIST($1), $3);
/*%
$$ = dispatch2(assoc_new, $1, $3);
%*/
}
| tLABEL arg_value
{
/*%%%*/
$$ = list_append(NEW_LIST(NEW_LIT(ID2SYM($1))), $2);
/*%
$$ = dispatch2(assoc_new, $1, $2);
%*/
}
;

We have the fat-arrow syntax again (arg_value tASSOC arg_value) and the JavaScript style (tLABEL arg_value); AFAIK, tLABEL is also the source of the restrictions on what sorts of symbols (no :$set, no :'this.that', ...) can be used with the JavaScript-style syntax. The current trunk parse.y matches 1.9.3 for Hash literals.

So the Hash literal syntax is hard-wired into the parser and you're stuck with fat arrows if you want to support 1.8.



Related Topics



Leave a reply



Submit