Confusion with empty block printing

When I typed the below in my IRB:

{}.class
#=> Hash #<~~ I got this one.

print {}.class
#NilClass

Why the above showing NilClass instead of Hash, but the below are
not?

print [].class
#Array=> nil
print (1…2).class
#Range=> nil
print 2.class
#Fixnum=> nil

because
print {}.class

is parsed as (print() {}).class

where {} is the closure block and not a Hash

Hans M. wrote in post #1101101:

Can you give me a bit knowledge about closure block concept. I didn’t
here about it.

where {} is the closure block and not a Hash

i mean the blocks you used in Confusion with block local variable declaration with block variable declaration within the pipe `|` - Ruby - Ruby-Forum

print thinks you want to call it with a block not with a hash

normally ruby functions when you add a block to them they ignored them
silency

On 12 March 2013 03:29, Love U Ruby [email protected] wrote:

Hans M. wrote in post #1101107:

normally ruby functions when you add a block to them they ignored them
silency

I am thinking when IRB sees that print {}.class, Is there any chance
to treat it as (print {}).class #=> NilClass ?

I’m pretty sure you want: print( {}.class )
But that’s not what you asked for.

This is pretty simple syntax stuff.

Matthew K. wrote in post #1101134:

I’m pretty sure you want: print( {}.class )
But that’s not what you asked for.

This is pretty simple syntax stuff.

See when typed in IRB the below it gives

{}.class
#=> Hash

And Hans said IRB treat print {}.class as (print {}).class which
causes the output as Nilclass.

But I was thinking (print {}).class also results NilClass. So which is
the one IRB actually recognized to give the output NilClass.

here I am making my confusions are more specific:

print(1…2).class
1…2=> NilClass

print (1…2).class
Range=> nil

Why the below 2 produces different output? How does IRB read the
above?

print[].class
NoMethodError: undefined method []' for nil:NilClass from (irb):5 from C:/Ruby193/bin/irb:12:in

print [].class
Array=> nil

How does IRB read the above?

print{}.class
=> NilClass

print {}.class
=> NilClass

Why here both lines giving the same outputs unlike the above 2 ?

Hans M. wrote in post #1101107:

normally ruby functions when you add a block to them they ignored them
silency

I am thinking when IRB sees that print {}.class, Is there any chance
to treat it as (print {}).class #=> NilClass ?

Please elaborate on the ways you have attempted to solve this problem
yourself, as a basic courtesy to others on this list.

http://www.catb.org/esr/faqs/smart-questions.html#beprecise

Specifically: “Describe the diagnostic steps you took to try and pin
down the problem yourself before you asked the question.”

You are messing up your code because you did not use parentheses,
leaving to ruby the task to guess what you wanted to do.

On Tue, Mar 12, 2013 at 01:41:09PM +0900, Love U Ruby wrote:

here I am making my confusions are more specific:

print(1…2).class
1…2=> NilClass

print (1…2).class
Range=> nil
(print(1…2)).class
1…2=> NilClass

print ((1…2).class)
Range=> nil

How does IRB read the above?

(print[]).class
NoMethodError: undefined method `[]’ for nil:NilClass

print ([].class)
Array=> nil

Think about what’s going on when you are using or not a space character

print{}.class
=> NilClass

print {}.class
=> NilClass

This one is a bit tricker but as you are already be told, the {} is
taken
as a block and not as a Hash. So both are interpreted in the same way.

(print{}).class
=> NilClass
(print {}).class
=> NilClass

Fortunately you won’t have to do this often, won’t you ?
Anyway what you probably wanted to do is this:

print({}.class)
Hash=> nil

First of all thanks to all guys who has shown interest in my post.

Keeping in mind @Matthew’s instructions I did the below. Hope now I am
able to clear my question once again to all the Experts out there.

C:>irb --simple-prompt --noecho

{}.class
[].class
(1…2).class
puts (1…2).class
Range

puts [].class
Array

puts {}.class
print {}.class
p {}.class

Very strange behaviour {}.class is showing with every printing
statement. But which is not the case with [] and (1..2). Now to see
the class {} I am requiring to add (). ~~~ actually my question was
why I need to do add () that with {} only, which is not needed with
[] and (1..3) ?

puts ({}.class)
Hash

p ({}.class)
Hash

print ({}.class)
Hash>>

Please let me know if you have any confusion to understand.

BECAUSE { } are used for hashes AND blocks … in this context you use
it as a block, not as a Hash …

thats why

puts {:e=>4}

raises an SYNTAXERROR

Stop using irb. Write a .rb file and run it. Then you will (hopefully)
see
that:

  1. print needs a “\n” to push output to the next line

    print ‘h’
    print ‘i’
    print “p\ncat”

  2. anything that starts with"#=>" isn’t real output; it’s stuff irb
    does

    x = 3 # no output

2b) those things are the VALUE OF THE PREVIOUS EXPRESSION

puts '#=> ' + x.inspect
  1. print has a value of nil

    x = print(’’) # x is now nil
    puts '#=> ’ + x.inspect # see?

3b) foo.class has a value of the object that foo is a new one of

foo = Object.new
foo2 = foo.class.new
  1. these are the same:

    print {}

    print do
    end

4b) print {} outputs nothing, and still has a value of nil
4c) nil.class has a value of NilClass

Sent from my phone, so excuse the typos.

Note that one of my points was that the following are the same:

print {}

print do
end

See also:

5.times { }

5.times do
end

But this is different:

print nil, {}

Also, ruby method calls have optional parentheses:

3.inspect
3.inspect()

foo
foo()

print 'x'
print( 'x' )

The interpreter always reads curlies {} as a block unless it makes no
sense
to do so. Parens and commas make it clear it’s a variable (and thus a
Hash).

Sent from my phone, so excuse the typos.

Humm,

Only within the () it is understood by IRB that i am feeding it a
Hash, otherwise error.

puts {:a => 4}
SyntaxError: (irb):17: syntax error, unexpected tASSOC, expecting ‘}’
puts {:a => 4}
^
from C:/Ruby193/bin/irb:12:in `’

puts {:a => 4}.class
SyntaxError: (irb):18: syntax error, unexpected tASSOC, expecting ‘}’
puts {:a => 4}.class
^
from C:/Ruby193/bin/irb:12:in `’
============================

puts ({:a => 4}.class)
Hash
============================

Strange it is. would not it?

Am 12.03.2013 08:55, schrieb Love U Ruby:

Please let me know if you have any confusion to understand.

Among the repliers there hasn’t been any confusion at all.

You’re question had been answered in the very first reply
(and additionally several times in later posts) so please
don’t ask the same question five times but instead try to
read the answers more carefully.

To clarify (hopefully) even more: this has nothing to do with IRB.
It’s the Ruby parser that needs and follows rules on how to
treat ambiguous expressions (like any parser does).

A different example: 2 + 3 * 4

This is parsed as 2 + (3 * 4) according to the rules for
operator precedence. If you want to enforce a different
interpretation of this expression, you need to make that clear
to the parser by adding some parentheses, e.g. (2 + 3) * 4

Same for your question: if you want {} to be interpreted as
a hash you need to make that clear to the parser.

Thanks for your re-explanation @Matthew and @Hans. This is how IRB works
I understood.

print nil, {}
{}>>
?> ^C

print nil, {}.class
Hash>>

Now this thread can be closed.

Thanks to all guys who helped me to understand this micro concept. :slight_smile:

unknown wrote in post #1101202:

Thank you very much to you for your effort to explain me the topic in
different way.

A different example: 2 + 3 * 4

This is parsed as 2 + (3 * 4) according to the rules for
operator precedence. If you want to enforce a different
interpretation of this expression, you need to make that clear
to the parser by adding some parentheses, e.g. (2 + 3) * 4

Same for your question: if you want {} to be interpreted as
a hash you need to make that clear to the parser.

The whole topic is understood by me.