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`, but the below are not?

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

···

--
Posted via http://www.ruby-forum.com/.

because
print {}.class

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

where {} is the closure block and not a Hash

···

--
Posted via http://www.ruby-forum.com/.

i mean the blocks you used in http://www.ruby-forum.com/topic/4411871

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

···

--
Posted via http://www.ruby-forum.com/.

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 `<main>'

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 ?

···

--
Posted via http://www.ruby-forum.com/\.

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)

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

···

--
Posted via http://www.ruby-forum.com/\.

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

···

--
Posted via http://www.ruby-forum.com/\.

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 `<main>'

puts {:a => 4}.class

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

···

============================

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

Hash

Strange it is. would not it?

--
Posted via http://www.ruby-forum.com/\.

Thanks for your re-explanation. This is how IRB works I understood.

print nil, {}

{}>>
?> ^C

print nil, {}.class

Now this thread can be closed.

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

···

--
Posted via http://www.ruby-forum.com/\.

Hans Mackowiak 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

--
Posted via http://www.ruby-forum.com/\.

Hans Mackowiak 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 ?

···

--
Posted via http://www.ruby-forum.com/\.

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."

···

On 12/03/13 15:11, 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

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 `<main>'

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 ?

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

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

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 `<main>'
>> print .class
Array=> 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

···

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

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

--
Posted via http://www.ruby-forum.com/\.

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.

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.

···

Am 12.03.2013 08:55, schrieb Love U Ruby:

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

--
<https://github.com/stomar/&gt;

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

This is pretty simple syntax stuff.

···

On 12 March 2013 03:29, Love U Ruby <lists@ruby-forum.com> wrote:

Hans Mackowiak 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 ?

--
  Matthew Kerwin, B.Sc (CompSci) (Hons)
  http://matthew.kerwin.net.au/

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

3. `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

4. 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.

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.

···

--
Posted via http://www.ruby-forum.com/\.

Matthew Kerwin 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`.

···

--
Posted via http://www.ruby-forum.com/\.