Callable class with block

Hi everyone,

I would like to know why the following code does not work :

···

-----
class A

  def A.[](*args,&block)
    result = self.new( *args )
    if block
      yield result
      result.end
    end
    return result
  end

  def end()
    puts "end"
  end

end

A[] do |a|
  puts "a #{a.inspect}"
end
-----

When I want to execute this script, the interpreter outputs the
following error :
--
d:/DEV/XRVG/bug.rb:18: parse error, unexpected kDO, expecting $
A[] do |a|
--

If I write "A.[] do |a|" instead of "A[] do |a|", it is OK and
outputs:
----
a #<A:0x28ee264>
end
----

Any idea ?
Any help appreciated !! Thanks in advance.

method can't take block unless you do

A.send '' do
end

a @ http://drawohara.com/

···

On Jan 12, 2008, at 10:54 AM, blondinet wrote:

Any idea ?

--
sleep is the best meditation.
h.h. the 14th dalai lama

That is interesting. With 1.8.6, I get results like this...

irb(main):001:0> class C
irb(main):002:1> def
irb(main):003:2> yield
irb(main):004:2> end
irb(main):005:1> end
=> nil
irb(main):006:0 c = C.new
=> #<C:0x2dfac1c>
irb(main):007:0> c
LocalJumpError: no block given <<<interesting part
      from (irb):3:in `'
      from (irb):7
irb(main):008:0> c {}
SyntaxError: compile error
(irb):8: syntax error, unexpected '{', expecting $end
c {}
     ^
      from(irb):8
irb(main):009:0> c. {}
=> nil

Bug maybe? I can't think of a reason why the parser would need to
separate from .
Hmm...

Todd

···

On Jan 12, 2008 11:54 AM, blondinet <jblondinet@yahoo.com> wrote:

Hi everyone,

I would like to know why the following code does not work :
-----
class A

  def A.(*args,&block)
    result = self.new( *args )
    if block
      yield result
      result.end
    end
    return result
  end

  def end()
    puts "end"
  end

end

A do |a|
  puts "a #{a.inspect}"
end

Thanks for your response. However, I do not really understand why such
a behavior : for me, Class is just a shortcut for Class., which is
just a shortcut for Class.send '' ... Where am I wrong ?

···

On 12 jan, 22:00, "ara.t.howard" <ara.t.how...@gmail.com> wrote:

On Jan 12, 2008, at 10:54 AM, blondinet wrote:

> Any idea ?

method can't take block unless you do

A.send '' do
end

a @http://drawohara.com/
--
sleep is the best meditation.
h.h. the 14th dalai lama

Thanks Todd for your analysis.
Your example is even striking than mine, and I share your opinion on
this strange "feature" : that a block is required and cannot be given
with the same syntax seems to me a bit "ugly".
Any other opinion ? As a beginner on this forum, I do not know yet
what to do with this ...

···

On 13 jan, 10:56, Todd Benson <caduce...@gmail.com> wrote:

On Jan 12, 2008 11:54 AM, blondinet <jblondi...@yahoo.com> wrote:

> Hi everyone,

> I would like to know why the following code does not work :
> -----
> class A

> def A.(*args,&block)
> result = self.new( *args )
> if block
> yield result
> result.end
> end
> return result
> end

> def end()
> puts "end"
> end

> end

> A do |a|
> puts "a #{a.inspect}"
> end

That is interesting. With 1.8.6, I get results like this...

irb(main):001:0> class C
irb(main):002:1> def
irb(main):003:2> yield
irb(main):004:2> end
irb(main):005:1> end
=> nil
irb(main):006:0 c = C.new
=> #<C:0x2dfac1c>
irb(main):007:0> c
LocalJumpError: no block given <<<interesting part
      from (irb):3:in `'
      from (irb):7
irb(main):008:0> c {}
SyntaxError: compile error
(irb):8: syntax error, unexpected '{', expecting $end
c {}
     ^
      from(irb):8
irb(main):009:0> c. {}
=> nil

Bug maybe? I can't think of a reason why the parser would need to
separate from .
Hmm...

Todd

blondinet wrote:

···

On 12 jan, 22:00, "ara.t.howard" <ara.t.how...@gmail.com> wrote:

On Jan 12, 2008, at 10:54 AM, blondinet wrote:

Any idea ?

method can't take block unless you do

A.send '' do
end

a @http://drawohara.com/
--
sleep is the best meditation.
h.h. the 14th dalai lama

Thanks for your response. However, I do not really understand why such
a behavior : for me, Class is just a shortcut for Class., which is
just a shortcut for Class.send '' ... Where am I wrong ?

Ruby's parser doesn't allow a block to follow .

--
RMagick: http://rmagick.rubyforge.org/
RMagick 2: http://rmagick.rubyforge.org/rmagick2.html

As this behavior is inherited in 1.9 too :(, I'd say somebody cross
posting this to ruby-core maybe.
Personally I'd love to have that changed.

Cheers
Robert

···

On Jan 13, 2008 6:24 PM, blondinet <jblondinet@yahoo.com> wrote:

On 13 jan, 10:56, Todd Benson <caduce...@gmail.com> wrote:

> On Jan 12, 2008 11:54 AM, blondinet <jblondi...@yahoo.com> wrote:
>
>
>
> > Hi everyone,
>
> > I would like to know why the following code does not work :
> > -----
> > class A
>
> > def A.(*args,&block)
> > result = self.new( *args )
> > if block
> > yield result
> > result.end
> > end
> > return result
> > end
>
> > def end()
> > puts "end"
> > end
>
> > end
>
> > A do |a|
> > puts "a #{a.inspect}"
> > end
>
> That is interesting. With 1.8.6, I get results like this...
>
> irb(main):001:0> class C
> irb(main):002:1> def
> irb(main):003:2> yield
> irb(main):004:2> end
> irb(main):005:1> end
> => nil
> irb(main):006:0 c = C.new
> => #<C:0x2dfac1c>
> irb(main):007:0> c
> LocalJumpError: no block given <<<interesting part
> from (irb):3:in `'
> from (irb):7
> irb(main):008:0> c {}
> SyntaxError: compile error
> (irb):8: syntax error, unexpected '{', expecting $end
> c {}
> ^
> from(irb):8
> irb(main):009:0> c. {}
> => nil
>
> Bug maybe? I can't think of a reason why the parser would need to
> separate from .
> Hmm...
>
> Todd

Thanks Todd for your analysis.
Your example is even striking than mine, and I share your opinion on
this strange "feature" : that a block is required and cannot be given
with the same syntax seems to me a bit "ugly".
Any other opinion ? As a beginner on this forum, I do not know yet
what to do with this ...

--
http://ruby-smalltalk.blogspot.com/

---
Whereof one cannot speak, thereof one must be silent.
Ludwig Wittgenstein

Hello Tim, thank you for your response. However I think it is a bit
erroneous, since in my example, "A. do |a|" works !!
Anyway, I will go with it, even if it is the first time that I find
Ruby a bit incoherent, and I would like to know why ... (sigh)

P.S : by the way, Tim, thanks for your work on RMagick, it is quite
helpfull !!
      You may find interesting the following link http://xrvg.rubyforge.org/,
even if it just a beginning :frowning:

···

On 12 jan, 23:06, Tim Hunter <TimHun...@nc.rr.com> wrote:

blondinet wrote:
> On 12 jan, 22:00, "ara.t.howard" <ara.t.how...@gmail.com> wrote:
>> On Jan 12, 2008, at 10:54 AM, blondinet wrote:

>>> Any idea ?
>> method can't take block unless you do

>> A.send '' do
>> end

>> a @http://drawohara.com/
>> --
>> sleep is the best meditation.
>> h.h. the 14th dalai lama

> Thanks for your response. However, I do not really understand why such
> a behavior : for me, Class is just a shortcut for Class., which is
> just a shortcut for Class.send '' ... Where am I wrong ?

Ruby's parser doesn't allow a block to follow .

--
RMagick:http://rmagick.rubyforge.org/
RMagick 2:http://rmagick.rubyforge.org/rmagick2.html

is an operator (the index operator). I would expect to have
higher precedence than anything that follows it. Although implemented
as such, it should not be seen as a function call, IMHO.

If

    foo[i] #=> 42

Then I would expect

    foo[i] { }

to be the same as

    42 { }

which makes little sense.

···

On Jan 13, 8:16 pm, Robert Dober <robert.do...@gmail.com> wrote:

Personally I'd love to have that changed.

So operators that you can redefine and execute as a method cannot
except a block as a general rule of thumb?

I would think foo[i] { } would be parsed as (foo[i] { }) as a single
piece, especially if you defined it to receive a block.

···

On Jan 14, 2008 9:01 AM, Lars <larsch@belunktum.dk> wrote:

On Jan 13, 8:16 pm, Robert Dober <robert.do...@gmail.com> wrote:
> Personally I'd love to have that changed.

is an operator (the index operator). I would expect to have
higher precedence than anything that follows it. Although implemented
as such, it should not be seen as a function call, IMHO.

If

    foo[i] #=> 42

Then I would expect

    foo[i] { }

to be the same as

    42 { }

which makes little sense.

I am not sure I follow you, but as an anecdote I once wrote the
following method definition

def + x, &blk
  ...
end

when I realized that I could not go
  anything + 42 { 42 }
I was quite disappointed ...

Robert

···

On Jan 14, 2008 4:01 PM, Lars <larsch@belunktum.dk> wrote:

On Jan 13, 8:16 pm, Robert Dober <robert.do...@gmail.com> wrote:
> Personally I'd love to have that changed.

is an operator (the index operator). I would expect to have
higher precedence than anything that follows it. Although implemented
as such, it should not be seen as a function call, IMHO.

If

    foo[i] #=> 42

Then I would expect

    foo[i] { }

to be the same as

    42 { }

which makes little sense.

--
http://ruby-smalltalk.blogspot.com/

---
Whereof one cannot speak, thereof one must be silent.
Ludwig Wittgenstein

Ruby is smart so you don't have to be. But here, it works against us.

foo.(i) do
  puts 42
end

Mess around with removing the dot, putting the i in between the brackets, etfc.

···

On Jan 14, 2008, at 10:25 AM, Todd Benson wrote:

So operators that you can redefine and execute as a method cannot
except a block as a general rule of thumb?

I would think foo[i] { } would be parsed as (foo[i] { }) as a single
piece, especially if you defined it to receive a block.

I am not sure I follow you

I'm just trying to say that I don't think that what you suggest is
intuitive behaviour to everyone. I personally think that it doesn't
make sense from a syntax point-of-view. Operators and function calls
are syntactically different things. Function calls take optional block
arguments, operator don't. I doubt its even possible to construct an
unambigious syntax.

when I realized that I could not go
  anything + 42 { 42 }
I was quite disappointed ...

Consider

    def something; 42; end

    anything + something { 42 }

Would the block be passed to 'something' or the '+'?

···

On Jan 14, 5:22 pm, Robert Dober <robert.do...@gmail.com> wrote:

> I am not sure I follow you

I'm just trying to say that I don't think that what you suggest is
intuitive behaviour to everyone. I personally think that it doesn't
make sense from a syntax point-of-view. Operators and function calls
are syntactically different things. Function calls take optional block
arguments, operator don't. I doubt its even possible to construct an
unambigious syntax.

Sorry but that just does not make sense to me...

> when I realized that I could not go
> anything + 42 { 42 }
> I was quite disappointed ...

Consider

    def something; 42; end

    anything + something { 42 }

Would the block be passed to 'something' or the '+'?

Well this is for the parser to decide, right? But
a + s &b being a.send(:+,s,&b) would make more sense as we still could
easily override this via the following

a + s(&b)
a + s(){}
a + (s {})
Robert

···

On Jan 15, 2008 11:15 AM, Lars <larsch@belunktum.dk> wrote:

On Jan 14, 5:22 pm, Robert Dober <robert.do...@gmail.com> wrote:

--
http://ruby-smalltalk.blogspot.com/

---
Whereof one cannot speak, thereof one must be silent.
Ludwig Wittgenstein