Web Images Videos Maps News Shopping Gmail more »
Recently Visited Groups | Help | Sign in
Google Groups Home
yield does not take a block
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  Messages 1 - 25 of 49 - Collapse all  -  Translate all to Translated (View all originals)   Newer >
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
Daniel Brockman  
View profile  
 More options Jun 28 2005, 4:37 am
Newsgroups: comp.lang.ruby
From: Daniel Brockman <dan...@brockman.se>
Date: Tue, 28 Jun 2005 17:37:06 +0900
Local: Tues, Jun 28 2005 4:37 am
Subject: yield does not take a block
Under ruby 1.9.0 (2005-06-23) [i386-linux], irb 0.9.5(05/04/13),
these forms are not permitted:

    yield { .. }
    yield &..

But these are okay:

    Proc.new.call { .. }
    Proc.new.call &..

This is an oversight, right?

--
Daniel Brockman <dan...@brockman.se>


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
nobuyoshi nakada  
View profile  
 More options Jun 28 2005, 6:40 am
Newsgroups: comp.lang.ruby
From: nobuyoshi nakada <nobuyoshi.nak...@ge.com>
Date: Tue, 28 Jun 2005 19:40:16 +0900
Local: Tues, Jun 28 2005 6:40 am
Subject: Re: yield does not take a block
Hi,

At Tue, 28 Jun 2005 17:37:06 +0900,
Daniel Brockman wrote in [ruby-talk:146630]:

> Under ruby 1.9.0 (2005-06-23) [i386-linux], irb 0.9.5(05/04/13),
> these forms are not permitted:

>     yield { .. }
>     yield &..

> But these are okay:

>     Proc.new.call { .. }
>     Proc.new.call &..

> This is an oversight, right?

Right.

Index: eval.c
===================================================================
RCS file: /cvs/ruby/src/ruby/eval.c,v
retrieving revision 1.791
diff -U2 -p -r1.791 eval.c
--- eval.c      20 Jun 2005 09:59:58 -0000      1.791
+++ eval.c      28 Jun 2005 10:29:44 -0000
@@ -3201,4 +3201,18 @@ rb_eval(self, n)
            result = Qundef;    /* no arg */
        }
+       if (node->nd_body) {
+           PUSH_BLOCK(0, 0);
+           if ((state = EXEC_TAG()) == 0) {
+               struct BLOCK *prev = ruby_block->prev;
+               *ruby_block = *prev;
+               ruby_block->prev = prev;
+               ruby_block->block_obj = rb_eval(self, node->nd_body);
+               SET_CURRENT_SOURCE();
+               result = rb_yield_0(result, 0, 0, YIELD_PROC_CALL, node->nd_state);
+           }
+           POP_BLOCK();
+           if (state) rb_jump_tag(state);
+           break;
+       }
        SET_CURRENT_SOURCE();
        result = rb_yield_0(result, 0, 0, 0, node->nd_state);
Index: parse.y
===================================================================
RCS file: /cvs/ruby/src/ruby/parse.y,v
retrieving revision 1.387
diff -U2 -p -r1.387 parse.y
--- parse.y     12 Jun 2005 16:56:05 -0000      1.387
+++ parse.y     28 Jun 2005 10:15:29 -0000
@@ -231,5 +231,5 @@ static void void_stmts_gen _((struct par
 #define void_stmts(node) void_stmts_gen(parser, node)
 static void reduce_nodes _((NODE**));
-static void block_dup_check _((NODE*));
+static NODE *add_iter_block _((NODE*,NODE*));

 static NODE *block_append _((NODE*,NODE*));
@@ -1138,7 +1138,5 @@ command           : operation command_args      
                        $$ = new_fcall($1, $2);
                        if ($3) {
-                           block_dup_check($$);
-                           $3->nd_iter = $$;
-                           $$ = $3;
+                           $$ = add_iter_block($$, $3);
                        }
                        fixpos($$, $2);
@@ -1162,7 +1160,5 @@ command           : operation command_args      
                        $$ = new_call($1, $3, $4);
                        if ($5) {
-                           block_dup_check($$);
-                           $5->nd_iter = $$;
-                           $$ = $5;
+                           $$ = add_iter_block($$, $5);
                        }
                        fixpos($$, $1);
@@ -1186,7 +1182,5 @@ command           : operation command_args      
                        $$ = new_call($1, $3, $4);
                        if ($5) {
-                           block_dup_check($$);
-                           $5->nd_iter = $$;
-                           $$ = $5;
+                           $$ = add_iter_block($$, $5);
                        }
                        fixpos($$, $1);
@@ -2561,28 +2555,4 @@ primary          : literal
                    %*/
                    }
-               | kYIELD '(' call_args rparen
-                   {
-                   /*%%%*/
-                       $$ = new_yield($3);
-                   /*%
-                       $$ = dispatch1(yield, dispatch1(paren, $3));
-                   %*/
-                   }
-               | kYIELD '(' rparen
-                   {
-                   /*%%%*/
-                       $$ = NEW_YIELD(0, Qfalse);
-                   /*%
-                       $$ = dispatch1(yield, dispatch1(paren, arg_new()));
-                   %*/
-                   }
-               | kYIELD
-                   {
-                   /*%%%*/
-                       $$ = NEW_YIELD(0, Qfalse);
-                   /*%
-                       $$ = dispatch0(yield0);
-                   %*/
-                   }
                | kDEFINED opt_nl '(' {in_defined = 1;} expr rparen
                    {
@@ -2610,7 +2580,5 @@ primary           : literal
                    {
                    /*%%%*/
-                       block_dup_check($$);
-                       $2->nd_iter = $1;
-                       $$ = $2;
+                       $$ = add_iter_block($1, $2);
                        fixpos($$, $1);
                    /*%
@@ -3215,7 +3183,5 @@ block_call        : command do_block
                    {
                    /*%%%*/
-                       block_dup_check($1);
-                       $2->nd_iter = $1;
-                       $$ = $2;
+                       $$ = add_iter_block($1, $2);
                        fixpos($$, $1);
                    /*%
@@ -3296,4 +3262,20 @@ method_call      : operation paren_args
                    %*/
                    }
+               | kYIELD paren_args
+                   {
+                   /*%%%*/
+                       $$ = new_yield($2);
+                   /*%
+                       $$ = dispatch1(yield, dispatch1(paren, $2));
+                   %*/
+                   }
+               | kYIELD
+                   {
+                   /*%%%*/
+                       $$ = NEW_YIELD(0, Qfalse);
+                   /*%
+                       $$ = dispatch0(yield0);
+                   %*/
+                   }
                | tLPAREN compstmt ')' paren_args
                    {
@@ -7212,11 +7194,22 @@ aryset_gen(parser, recv, idx)
 }

-static void
-block_dup_check(node)
-    NODE *node;
+static NODE *
+add_iter_block(node, block)
+    NODE *node, *block;
 {
-    if (node && nd_type(node) == NODE_BLOCK_PASS) {
-       compile_error(PARSER_ARG "both block arg and actual block given");
+    if (node) {
+       switch (nd_type(node)) {
+         case NODE_YIELD:
+           if (!node->nd_body) {
+               nd_set_type(block, NODE_LAMBDA);
+               node->nd_body = block;
+               return node;
+           }
+         case NODE_BLOCK_PASS:
+           compile_error(PARSER_ARG "both block arg and actual block given");
+       }
     }
+    block->nd_iter = node;
+    return block;
 }

@@ -7794,13 +7787,22 @@ new_yield(node)
 {
     long state = Qtrue;
+    NODE *body = 0;

     if (node) {
-        no_blockarg(node);
-        if (nd_type(node) == NODE_ARRAY && node->nd_next == 0) {
+       switch (nd_type(node)) {
+         case NODE_BLOCK_PASS:
+           body = node;
+           node = node->nd_iter;
+           nd_set_type(body, NODE_LAMBDA);
+           body->nd_iter = 0;
+           break;
+         case NODE_ARRAY:
+           if (node->nd_next != 0) break;
             node = node->nd_head;
             state = Qfalse;
-        }
-        else if (node && nd_type(node) == NODE_SPLAT) {
+           break;
+         case NODE_SPLAT:
             state = Qtrue;
+           break;
         }
     }
@@ -7808,5 +7810,7 @@ new_yield(node)
         state = Qfalse;
     }
-    return NEW_YIELD(node, state);
+    node = NEW_YIELD(node, state);
+    node->nd_body = body;
+    return node;
 }

--
Nobu Nakada


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Yukihiro Matsumoto  
View profile  
 More options Jun 28 2005, 11:32 am
Newsgroups: comp.lang.ruby
From: Yukihiro Matsumoto <m...@ruby-lang.org>
Date: Wed, 29 Jun 2005 00:32:20 +0900
Local: Tues, Jun 28 2005 11:32 am
Subject: Re: yield does not take a block
Hi,

In message "Re: yield does not take a block"
    on Tue, 28 Jun 2005 17:37:06 +0900, Daniel Brockman <dan...@brockman.se> writes:

|Under ruby 1.9.0 (2005-06-23) [i386-linux], irb 0.9.5(05/04/13),
|these forms are not permitted:
|
|    yield { .. }
|    yield &..
|
|But these are okay:
|
|    Proc.new.call { .. }
|    Proc.new.call &..
|
|This is an oversight, right?

yield is a keyword to pass a value (and control) to the block attached
to the method.  I feel strange when I see yield passes a block to an
outer block.

                                                        matz.


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
James Britt  
View profile  
 More options Jun 28 2005, 11:49 am
Newsgroups: comp.lang.ruby
From: James Britt <jame...@neurogami.com>
Date: Wed, 29 Jun 2005 00:49:17 +0900
Local: Tues, Jun 28 2005 11:49 am
Subject: Re: yield does not take a block
Yukihiro Matsumoto wrote:

..

> yield is a keyword to pass a value (and control) to the block attached
> to the method.  I feel strange when I see yield passes a block to an
> outer block.

Is that good strange or bad strange?

James
--
http://www.ruby-doc.org - The Ruby Documentation Site
http://www.rubyxml.com  - News, Articles, and Listings for Ruby & XML
http://www.rubystuff.com - The Ruby Store for Ruby Stuff
http://www.jamesbritt.com  - Playing with Better Toys


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Yukihiro Matsumoto  
View profile  
 More options Jun 28 2005, 12:19 pm
Newsgroups: comp.lang.ruby
From: Yukihiro Matsumoto <m...@ruby-lang.org>
Date: Wed, 29 Jun 2005 01:19:16 +0900
Local: Tues, Jun 28 2005 12:19 pm
Subject: Re: yield does not take a block
Hi,

In message "Re: yield does not take a block"
    on Wed, 29 Jun 2005 00:49:17 +0900, James Britt <jame...@neurogami.com> writes:

|> yield is a keyword to pass a value (and control) to the block attached
|> to the method.  I feel strange when I see yield passes a block to an
|> outer block.
|
|Is that good strange or bad strange?

I feel bad strange.  Do you?

                                                        matz.


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
James Britt  
View profile  
 More options Jun 28 2005, 12:28 pm
Newsgroups: comp.lang.ruby
From: James Britt <jame...@neurogami.com>
Date: Wed, 29 Jun 2005 01:28:46 +0900
Local: Tues, Jun 28 2005 12:28 pm
Subject: Re: yield does not take a block

Yukihiro Matsumoto wrote:
> Hi,

> In message "Re: yield does not take a block"
>     on Wed, 29 Jun 2005 00:49:17 +0900, James Britt <jame...@neurogami.com> writes:

> |> yield is a keyword to pass a value (and control) to the block attached
> |> to the method.  I feel strange when I see yield passes a block to an
> |> outer block.
> |
> |Is that good strange or bad strange?

> I feel bad strange.  Do you?

No.  Good strange.

James


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Daniel Brockman  
View profile  
 More options Jun 28 2005, 1:30 pm
Newsgroups: comp.lang.ruby
From: Daniel Brockman <dan...@brockman.se>
Date: Wed, 29 Jun 2005 02:30:05 +0900
Local: Tues, Jun 28 2005 1:30 pm
Subject: Re: yield does not take a block

Yukihiro Matsumoto <m...@ruby-lang.org> writes:
> yield is a keyword to pass a value (and control) to the block
> attached to the method.  I feel strange when I see yield passes a
> block to an outer block.

I feel strange when I see these are not equivalent:

  def foo1 &block
    block.call &bar
  end

  def foo2
    Proc.new.call &bar
  end

  def foo3 &block
    yield &bar
  end

The middle one may be a weird idiom that should be phased out, but I
really think that calling a block captured into a variable should be
equivalent to using yield.

If foo1 and foo3 are not equivalent, then we have an inconsistency.

--
Daniel Brockman <dan...@brockman.se>


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Yukihiro Matsumoto  
View profile  
 More options Jun 28 2005, 3:45 pm
Newsgroups: comp.lang.ruby
From: Yukihiro Matsumoto <m...@ruby-lang.org>
Date: Wed, 29 Jun 2005 04:45:46 +0900
Local: Tues, Jun 28 2005 3:45 pm
Subject: Re: yield does not take a block
Hi,

In message "Re: yield does not take a block"
    on Wed, 29 Jun 2005 02:30:05 +0900, Daniel Brockman <dan...@brockman.se> writes:

|I feel strange when I see these are not equivalent:
|
|  def foo1 &block
|    block.call &bar
|  end
|
|  def foo2
|    Proc.new.call &bar
|  end
|
|  def foo3 &block
|    yield &bar
|  end

|If foo1 and foo3 are not equivalent, then we have an inconsistency.

Indeed we have inconsistency here if those two are not equivalent, but
I don't think consistency matters most in this case.  Using yield
emphasizes passing a value and control to a block given to the method.
On the other hand, "call"ing an block argument (&block) emphasizes
treating a block as a procedural object.  If they are focusing
different aspect, they might not be exact same.

It's not a technical issue.  Just a matter of how we feel when we see

  yield &bar

or

  yield {...}

I feel something strange (bad strange) when I see this, just because
it passes a block to another block, which is apparently strange,
whereas

  block.call &bar

does not make me feel bad strange, since it is valid syntax in the
microscopic view, even when it is semantically strange.

If you have shown me the reason "yield &bar" is not strange (and is
useful) other than consistency, I'd be glad to apply the Nobu's patch
in [ruby-talk:146636].

                                                        matz.


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Eric Mahurin  
View profile  
 More options Jun 28 2005, 4:17 pm
Newsgroups: comp.lang.ruby
From: Eric Mahurin <eric_mahu...@yahoo.com>
Date: Wed, 29 Jun 2005 05:17:41 +0900
Local: Tues, Jun 28 2005 4:17 pm
Subject: Re: yield does not take a block

--- Yukihiro Matsumoto <m...@ruby-lang.org> wrote:

I tend to agree that the yield should be made consistent with
block.call such that yield would basically be just an alias for
block.call (where block is the block given to the current
method).  I think any keyword that can reasonably be made to
look like a method call, should.  Makes the syntax more
consistent.  If you were starting over, I'd even suggest things
like if/while to be like (or actually) method calls.

but...

Personally, I don't think having yield as a keyword really adds
that much value to the language.  The only advantages I see
over explicitly having a &block arg and using block.call are a)
it looks like smalltalk, and b) rdoc parses it better.  I think
showing the &block on the def line makes the method interface
clearer up front.  I don't use yield at all and haven't missed
it.

__________________________________
Do you Yahoo!?
Yahoo! Mail - Find what you need with new enhanced search.
http://info.mail.yahoo.com/mail_250


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Ryan Leavengood  
View profile  
 More options Jun 28 2005, 4:49 pm
Newsgroups: comp.lang.ruby
From: "Ryan Leavengood" <mrc...@netrox.net>
Date: Wed, 29 Jun 2005 05:49:45 +0900
Local: Tues, Jun 28 2005 4:49 pm
Subject: Re: yield does not take a block
Eric Mahurin said:

> I tend to agree that the yield should be made consistent with
> block.call such that yield would basically be just an alias for
> block.call (where block is the block given to the current
> method).  I think any keyword that can reasonably be made to
> look like a method call, should.  Makes the syntax more
> consistent.  If you were starting over, I'd even suggest things
> like if/while to be like (or actually) method calls.

Though I understand matz's seeing the yielding of a block as a bad kind of
strangeness, I do think consistency is good. If yield and block.call are
different in any way that could be confusing, especially to all these new
Ruby users we've been getting lately. So I agree with Eric here.

I still would like to see a case where a block is yielded, and just how
that would be used. Sounds like potentially confusing code to me.

I also like the idea of if and while being methods, just as long as the
current syntax sugar is maintained.

> Personally, I don't think having yield as a keyword really adds
> that much value to the language.  The only advantages I see
> over explicitly having a &block arg and using block.call are a)
> it looks like smalltalk, and b) rdoc parses it better.  I think
> showing the &block on the def line makes the method interface
> clearer up front.  I don't use yield at all and haven't missed
> it.

I like yield as a keyword, and I think the only reason to use &block is
when you want to save the given block or do some other manipulation on it
(ask for its arity, etc.) It is a lot of extra typing to use an &block
parameter than just calling yield, especially if all you want to do is
yield a value. Conceptually I think the idea of 'yield'ing control to a
block is nice (though I suppose the idea of 'call'ing a block is just as
nice.) But I still don't think yield should be tossed (not that matz ever
would.)

Ryan


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Jim Freeze  
View profile  
 More options Jun 28 2005, 5:12 pm
Newsgroups: comp.lang.ruby
From: Jim Freeze <j...@freeze.org>
Date: Wed, 29 Jun 2005 06:12:15 +0900
Local: Tues, Jun 28 2005 5:12 pm
Subject: Re: yield does not take a block
* Ryan Leavengood <mrc...@netrox.net> [2005-06-29 05:49:45 +0900]:

> I like yield as a keyword, and I think the only reason to use &block is
> when you want to save the given block or do some other manipulation on it
> (ask for its arity, etc.) It is a lot of extra typing to use an &block
> parameter than just calling yield, especially if all you want to do is
> yield a value. Conceptually I think the idea of 'yield'ing control to a
> block is nice (though I suppose the idea of 'call'ing a block is just as
> nice.) But I still don't think yield should be tossed (not that matz ever
> would.)

The implicit passing of a block (that follows a method call) and
the 'yield' keyword is one of the key signatures of Ruby and one
that gives Ruby a great deal of power with very little typing.

If we had the principle of absolute explicitness for everything,
then it would be more difficult to write DSL's and we wouldn't
have nice apps like rails. In fact, we would probably even have
to add statement ending identifiers, like semicolons....run away run away...

--
Jim Freeze


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Eric Mahurin  
View profile  
 More options Jun 28 2005, 5:56 pm
Newsgroups: comp.lang.ruby
From: Eric Mahurin <eric_mahu...@yahoo.com>
Date: Wed, 29 Jun 2005 06:56:39 +0900
Local: Tues, Jun 28 2005 5:56 pm
Subject: Re: yield does not take a block
--- Jim Freeze <j...@freeze.org> wrote:

I really like the block passing thing in ruby too.   I also
think it to be one of the most distinguishing features over
many other languages.  What I don't like from the method
definition perspective, is that you have no control over
whether the block is not allowed, optional, or required.  I
would have liked being able to define my methods like this to
control it:

def block_prohibited(*args) ... end

def block_allowed(*args,&block=nil)
    ...
    block.call(...) if block
    ...
end

def block_required(*args,&block)
    ...
    block.call(...)
    ...
end

Of course these (at least the first and last) break
compatibility, so this ain't gonna happen.  But, this would
make sense relative the way other args are defined and assigned
default values.

____________________________________________________
Yahoo! Sports
Rekindle the Rivalries. Sign up for Fantasy Football
http://football.fantasysports.yahoo.com


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Jeremy Henty  
View profile  
 More options Jun 28 2005, 6:10 pm
Newsgroups: comp.lang.ruby
From: Jeremy Henty <jer...@chaos.org.uk>
Date: Tue, 28 Jun 2005 17:10:20 -0500
Local: Tues, Jun 28 2005 6:10 pm
Subject: Re: yield does not take a block
In article <20050628215637.45029.qm...@web41129.mail.yahoo.com>, Eric

Mahurin wrote:
> What I don't like ... is that you have no control over whether the
> block is not allowed, optional, or required.

What's wrong with:

  def i_hate_blocks
    raise "blocks suck" if block_given?
  end

Regards,

Jeremy Henty


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Bertram Scharpf  
View profile  
 More options Jun 28 2005, 6:24 pm
Newsgroups: comp.lang.ruby
From: Bertram Scharpf <li...@bertram-scharpf.de>
Date: Wed, 29 Jun 2005 07:24:14 +0900
Local: Tues, Jun 28 2005 6:24 pm
Subject: Re: yield does not take a block
Hi,

Am Mittwoch, 29. Jun 2005, 01:19:16 +0900 schrieb Yukihiro Matsumoto:

> In message "Re: yield does not take a block"
>     on Wed, 29 Jun 2005 00:49:17 +0900, James Britt <jame...@neurogami.com> writes:

> |> yield is a keyword to pass a value (and control) to the block attached
> |> to the method.  I feel strange when I see yield passes a block to an
> |> outer block.
> |
> |Is that good strange or bad strange?

> I feel bad strange.  Do you?

Logic demands to allow it. Prohibiting it would mean to
introduce an exception rule (POLS?).

Anyway, the programmer should be saved from fooling himself
inventing more and more complicated constructions.

Bad strange.

Bertram

--
Bertram Scharpf
Stuttgart, Deutschland/Germany
http://www.bertram-scharpf.de


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Eric Mahurin  
View profile  
 More options Jun 28 2005, 6:28 pm
Newsgroups: comp.lang.ruby
From: Eric Mahurin <eric_mahu...@yahoo.com>
Date: Wed, 29 Jun 2005 07:28:02 +0900
Local: Tues, Jun 28 2005 6:28 pm
Subject: Re: yield does not take a block
--- Jeremy Henty <jer...@chaos.org.uk> wrote:

> In article
> <20050628215637.45029.qm...@web41129.mail.yahoo.com>, Eric
> Mahurin wrote:

> > What I don't like ... is that you have no control over
> whether the
> > block is not allowed, optional, or required.

> What's wrong with:

>   def i_hate_blocks
>     raise "blocks suck" if block_given?
>   end

Of course.  I was exaggerating when I said you have "no
control".  But, that is kind-of ugly to have to do this for
every method doesn't want a block (most of them).  It would be
better if the iterpreter checked this at call time just like it
handles other args (checking the arity).  As it is now, you can
pass a block to just about any method that doesn't want a block
and no complaint will be given.  If we didn't have
yield/block_given?, this could have been easily handled with
the &block syntax and something like arity.

I'm not suggesting to get rid of yield... I'm just ranting.

__________________________________
Yahoo! Mail
Stay connected, organized, and protected. Take the tour:
http://tour.mail.yahoo.com/mailtour.html


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Ryan Leavengood  
View profile  
 More options Jun 28 2005, 6:40 pm
Newsgroups: comp.lang.ruby
From: "Ryan Leavengood" <mrc...@netrox.net>
Date: Wed, 29 Jun 2005 07:40:10 +0900
Local: Tues, Jun 28 2005 6:40 pm
Subject: Re: yield does not take a block
Eric Mahurin said:

> As it is now, you can
> pass a block to just about any method that doesn't want a block
> and no complaint will be given.

There will also be no bad side affects, besides the code in the block is
never  executed. So essentially the person does not understand the
interface to the given method. I don't agree the language should enforce
this, especially given the dynamic nature of Ruby. In fact this reminds me
of all the static-typing sort of arguments we get here now and then.

I equate the above argument to someone saying this should give a warning:

false && a_very_important_method_call()

A language can only go so far in trying to stop bad programmers before it
starts hurting good programmers.

Ryan


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
James Britt  
View profile  
 More options Jun 28 2005, 6:49 pm
Newsgroups: comp.lang.ruby
From: James Britt <jame...@neurogami.com>
Date: Wed, 29 Jun 2005 07:49:16 +0900
Local: Tues, Jun 28 2005 6:49 pm
Subject: Re: yield does not take a block

There's a lot to be said for consistency in a language, to avoid the
complexity introduced by "This is the case, except when it's not."

Ruby has fairly few of these instances, which is part of its appeal for me.

It's nice to be able to layout a small set of ground rules and say that
everything you can derive from them is valid.

> Anyway, the programmer should be saved from fooling himself
> inventing more and more complicated constructions.

Saved in what way?

Languages should be designed to enable developers, not protect them from
themselves.

James
--

http://www.ruby-doc.org - The Ruby Documentation Site
http://www.rubyxml.com  - News, Articles, and Listings for Ruby & XML
http://www.rubystuff.com - The Ruby Store for Ruby Stuff
http://www.jamesbritt.com  - Playing with Better Toys


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Eric Mahurin  
View profile  
 More options Jun 28 2005, 7:23 pm
Newsgroups: comp.lang.ruby
From: Eric Mahurin <eric_mahu...@yahoo.com>
Date: Wed, 29 Jun 2005 08:23:47 +0900
Local: Tues, Jun 28 2005 7:23 pm
Subject: Re: yield does not take a block
--- Ryan Leavengood <mrc...@netrox.net> wrote:

You could say the same thing about passing too many arguments
to a method.  Why does Ruby check this case now?  ... because
it is an obvious error that can easily be checked for.  The
same could be done automatically for code blocks to methods -
with the right language changes.  Having the yield keyword does
make it a little more difficult.

I have no idea what this has to do with static typing.  I am a
very strong proponent of duck typing.  We are talking about
whether a certain argument (the code block) exists in the call
not what type it is.  As it stands now, this code block is
actually statically typed to Proc and not just an object that
responds to call and arity.  I would prefer it to be any old
duck that can call and arity.

__________________________________
Discover Yahoo!
Stay in touch with email, IM, photo sharing and more. Check it out!
http://discover.yahoo.com/stayintouch.html


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Daniel Brockman  
View profile  
 More options Jun 28 2005, 10:21 pm
Newsgroups: comp.lang.ruby
From: Daniel Brockman <dan...@brockman.se>
Date: Wed, 29 Jun 2005 11:21:25 +0900
Local: Tues, Jun 28 2005 10:21 pm
Subject: Re: yield does not take a block

Yukihiro Matsumoto <m...@ruby-lang.org> writes:
> If you have shown me the reason "yield &bar" is not strange (and is
> useful) other than consistency, I'd be glad to apply the Nobu's
> patch in [ruby-talk:146636].

I don't have any other reason than consistency.  Having used Ruby 1.8
up until yesterday, yield and Proc.new.call are equivalent in my mind.
It seems I will have to drop that identification when moving to 1.9.

The fact that blocks cannot take blocks pre-1.9 has always bugged me,
and I certainly don't think there's anything strange about this code:

    define_method :foo do |*args, &block| ... end

However, I agree that most uses of these metablocks (if you will)
probably do not coincide with the use cases of the yield keyword.

So I will not be upset if Nobu's patch is not applied.  I will just
make a mental note that Yield Does Not Take a Block and move on.
Should I ever be tempted to pass a block to yield, I will remember
that it doesn't work, and simply call the block explicitly instead.

I guess the reason why yield &block is not strange to me is that the
yield statement yields values, and blocks are just special values.

--
Daniel Brockman <dan...@brockman.se>


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Devin Mullins  
View profile  
 More options Jun 28 2005, 10:34 pm
Newsgroups: comp.lang.ruby
From: Devin Mullins <twif...@comcast.net>
Date: Wed, 29 Jun 2005 11:34:13 +0900
Local: Tues, Jun 28 2005 10:34 pm
Subject: Re: yield does not take a block

Eric Mahurin wrote:
>Having the yield keyword does
>make it a little more difficult.

Actually, it makes it a lot more difficult. Consider:

irb(main):039:0> def blah
irb(main):040:1> eval "yield", binding
irb(main):041:1> end
=> nil
irb(main):042:0> blah { puts 5 }
5
=> nil

In any case, I don't have a strong opinion on the "arity" of blocks. I
*do* have a fairly strong opinion that consistency should be favored
wherever possible, but nothing real to back it up, other than that (the
lack of) it is what I dislike most about Java (primitives, null,
Serializable, java.lang...), and it is what I like most about Ruby.

>As it stands now, this code block is
>actually statically typed to Proc and not just an object that
>responds to call and arity.  I would prefer it to be any old
>duck that can call and arity.

Agreed. That code be done without changing any of the current syntax, too.

irb(main):047:0> blah(&proc{puts 5})
5
=> nil

irb(main):048:0> p = Object.new
=> #<Object:0x2b31990>
irb(main):049:0> class << p
irb(main):050:1> def call
irb(main):051:2> puts 5
irb(main):052:2> end
irb(main):053:1> end
=> nil
irb(main):054:0> blah(&p)
TypeError: wrong argument type Object (expected Proc)
        from (irb):54
        from :0

Boo. :(

Devin
But yay, Ruby, in general.

Also, yay for just having an irb session sitting around in my taskbar.
Does that make me a packrat?


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Robert Klemme  
View profile  
 More options Jun 29 2005, 6:03 am
Newsgroups: comp.lang.ruby
From: "Robert Klemme" <bob.n...@gmx.net>
Date: Wed, 29 Jun 2005 12:03:58 +0200
Local: Wed, Jun 29 2005 6:03 am
Subject: Re: yield does not take a block

Note though that yield and &c.call work quite differently.  This has for
example performance implications.

Kind regards

    robert


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Eric Mahurin  
View profile  
 More options Jun 29 2005, 8:37 am
Newsgroups: comp.lang.ruby
From: Eric Mahurin <eric_mahu...@yahoo.com>
Date: Wed, 29 Jun 2005 21:37:16 +0900
Local: Wed, Jun 29 2005 8:37 am
Subject: Re: yield does not take a block
--- Robert Klemme <bob.n...@gmx.net> wrote:

> Note though that yield and &c.call work quite differently.
> This has for example performance implications.

I didn't know about this advantage.  From my quick benchmarks,
I found yield to take half the time as Proc#call in a loop with
the block being empty.  I'd imagine the performance difference
is because yield is working with a statically typed Proc,
whereas call is using a normal dynamically typed object to
#call.  I'd imagine as ruby matures, the performance difference
between these two would become negligible or zero.  I'd hope at
some point ruby would make optimizations when it knows the
exact class of an object - do method lookup at compile time.

__________________________________
Yahoo! Mail Mobile
Take Yahoo! Mail with you! Check email on your mobile phone.
http://mobile.yahoo.com/learn/mail


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Robert Klemme  
View profile  
 More options Jun 29 2005, 8:46 am
Newsgroups: comp.lang.ruby
From: "Robert Klemme" <bob.n...@gmx.net>
Date: Wed, 29 Jun 2005 14:46:37 +0200
Local: Wed, Jun 29 2005 8:46 am
Subject: Re: yield does not take a block

Eric Mahurin wrote:
> --- Robert Klemme <bob.n...@gmx.net> wrote:
>> Note though that yield and &c.call work quite differently.
>> This has for example performance implications.

> I didn't know about this advantage.  From my quick benchmarks,
> I found yield to take half the time as Proc#call in a loop with
> the block being empty.  I'd imagine the performance difference
> is because yield is working with a statically typed Proc,
> whereas call is using a normal dynamically typed object to
> #call.

Yes.  More preceisely the overhead of &b.call is in the creation of the
proc (i.e. transforming the block, storing the closure and registering the
result with GC) - with 'yield' there is no object around.

>  I'd imagine as ruby matures, the performance difference
> between these two would become negligible or zero.

Probably but IMHO not very likely.  Maybe the gap closes but my guess
would be that it remains significant.

>  I'd hope at
> some point ruby would make optimizations when it knows the
> exact class of an object - do method lookup at compile time.

IMHO this is close to impossible as knowing the class of an object tells
you nothing definite about which methods it supports and what signature
they have. (see all the discussions about static typing)

Kind regards

    robert


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Eric Mahurin  
View profile  
 More options Jun 29 2005, 9:58 am
Newsgroups: comp.lang.ruby
From: Eric Mahurin <eric_mahu...@yahoo.com>
Date: Wed, 29 Jun 2005 22:58:53 +0900
Local: Wed, Jun 29 2005 9:58 am
Subject: Re: yield does not take a block
--- Robert Klemme <bob.n...@gmx.net> wrote:

> Eric Mahurin wrote:
> > --- Robert Klemme <bob.n...@gmx.net> wrote:
> >  I'd hope at
> > some point ruby would make optimizations when it knows the
> > exact class of an object - do method lookup at compile
> time.

> IMHO this is close to impossible as knowing the class of an
> object tells
> you nothing definite about which methods it supports and what
> signature
> they have. (see all the discussions about static typing)

Probably correct.  I think there may be a little too much
flexibility in the ruby language that will prevent future
optimizations.  I think the destructive modification of a class
and of an object's class (making its class a singleton) are the
main culprits.  If these were non-destructive (returning a new
class or new object with a singleton class), it would have
allowed more optimization.  To me, discussions about
destructive vs. non-destructive methods (reverse! vs. reverse)
are nothing compared to these.

____________________________________________________
Yahoo! Sports
Rekindle the Rivalries. Sign up for Fantasy Football
http://football.fantasysports.yahoo.com


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Adam P. Jenkins  
View profile  
 More options Jun 29 2005, 11:58 am
Newsgroups: comp.lang.ruby
From: "Adam P. Jenkins" <tho...@theshire.com>
Date: Wed, 29 Jun 2005 11:58:34 -0400
Local: Wed, Jun 29 2005 11:58 am
Subject: Re: yield does not take a block

Eric Mahurin wrote:
> Personally, I don't think having yield as a keyword really adds
> that much value to the language.  The only advantages I see
> over explicitly having a &block arg and using block.call are a)
> it looks like smalltalk, and b) rdoc parses it better.  I think
> showing the &block on the def line makes the method interface
> clearer up front.  I don't use yield at all and haven't missed
> it.

I completely agree with this.  I think closures are one of the most
useful features of Ruby, but I still don't understand what the point of
having blocks and yield is.  In all other languages I've used that have
closures, such as Scheme, ML, Haskell, OCaml, and even Javascript, a
closure is just an object like any other object, that happens to have a
special literal syntax for creating them.  If you want to pass a closure
to another function, you just pass it like any other argument.

The way ruby does it with blocks/yield has several disadvantages:

1) There's an arbitrary limit of 1 on the number of blocks you can pass
to a function.  If you want to pass more than 1, you need to convert all
but the last block to a proc.

2) The block argument can be implicit, so you can't see from the
function signature that there is a block argument.

3) You get a problem akin to Java's primitive/Object separation, where
in some contexts you need a block, and have to convert another callable
object to a block, and in other contexts you need a proc, and have to
convert a block to a proc.

Let me expand on the last item.  In functional languages like Scheme,
ML, or Haskell, all functions are closures, whether they're named or
anonymous, and can be used interchangeably.  So, say I wanted to apply a
function to each element of a list, I'd write something like this in ML:

     for_each myArray print

for_each takes a list as its first argument, and a function with 1
parameter as its second argument, and applies the function to each
element of the list.  In Ruby, since there's a distinction between
blocks, closures, and functions, I can't just pass print, even though
it's a function of 1 parameter.  Rather I have to wrap print in a block:

     myArray.each { |elem| print elem }

Wouldn't it have been cool to just be able to write:

     myArray.each print

Overall, it's not a big problem, but I do think the fact that there's a
  distinction between blocks, procs, and functions is one of the main
warts in the Ruby language.

Adam


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Messages 1 - 25 of 49   Newer >
« Back to Discussions « Newer topic     Older topic »

Create a group - Google Groups - Google Home - Terms of Service - Privacy Policy
©2009 Google