Javascript is well-known for its quirks. Afterall, the language was designed and prototyped in only 10 days by Brendan Eich in 1995 (the year of the first public release of Ruby!). At the time Netscape was competing with Microsoft during the First Browser War, some of the quirks are still present to this day.

In Javascript,

'3' + '2';
// => "32"

concatenates the string but:

'3' - '2';
// => 1

returns the difference.

Or in Javascript:

true == true;
// => true
false == false;
// => true
true == false;
// => false
// So far so good.

[] == ![];
// => true
// A bit strange, but ok...

true == [];
// => false
true == ![];
// => false
// Eing?!

false == [];
// => true
false == ![];
// => true
// Sure...

is always fun, but surely Ruby is not like that! Ruby is clear and consistent language…

Example 1

defined?(foo)
# => nil
if false
  foo = 'never executed'
end
foo
# => nil
defined?(foo)
# => "local-variable"

Example 2

foo = (1)
# => 1 
foo = ()
# => nil 
() == nil
# => true
!() == true
# => true

() has no statements and is treated like an empty expression that represents nil.

Example 3

"foo" "bar"
# => "foobar"

is a valid ruby expression to concatenate strings.

Example 4

3 - 1
# => 2 
3-1
# => 2 
3 -1
# => 2 
[1, 2, 3].length -1
# raise ArgumentError (wrong number of arguments (given 1, expected 0))

is being parsed as [1, 2, 3].length(-1) instead of ([1, 2, 3].length) -1.

Example 5

t = Time.new(2018, 7, 1)
# => 2018-07-01 00:00:00 +0100 
t
# => 2018-07-01 00:00:00 +0100 
t.utc
# => 2018-06-30 23:00:00 UTC 
t
# => 2018-06-30 23:00:00 UTC

Although it’s not a bang method !, #utc does modify the object.