f



procs/blocks - blocks with procs, blocks with blocks?

Well, maybe not blocks with blocks but blocks with yield?  although
right now, I only have a fix for procs with blocks and not blocks with
blocks via blocks with yield when a proc block is not in stock...

class Proc
  alias __proc_block_call call
  alias __proc_block_indexer []
  
  def call(*args, &block)
    __proc_block_call(*(block.nil? ? args : args << block))
  end
  
  def [](*args, &block)
    __proc_block_indexer(*(block.nil? ? args : args << block))
  end
end

-----
usage

prc = Proc.new {|arg, proc_block|
  p arg
  proc_block[arg]
}

prc.call("Foo") {|*what|
  puts "Got #{what.length} whats -- #{what.inspect}"
}

produces:

"Foo"
Got 1 whats -- ["Foo"]


- also - it looks like the indexer function cannot take a block (parse
error) - why?
0
mhm26 (28)
8/5/2004 7:20:10 PM
comp.lang.ruby 48886 articles. 0 followers. Post Follow

3 Replies
1284 Views

Similar Articles

[PageSpeed] 3

here is my latest `update' to the idea:

--- code ---
class Proc
  alias __proc_block_call call
  alias __proc_block_indexer []

  @@blocks = []
  
  def Proc.yield(*args)
    fail "No current proc context"          if @@blocks.empty?
    raise LocalJumpError, "no block given"  if @@blocks[-1].nil?
    # Maybe just @block.call? - This allows for recursion, though
    @@blocks[-1].__proc_block_call(*args)
  end

  def Proc.block_given?(*args)
    fail "No current proc context"          if @@blocks.empty?
    !@@blocks[-1].nil?
  end

  def yield(*args)
    Proc.yield(*args)
  end

  def block_given?
    Proc.block_given?
  end

  def call(*args, &block)
    @@blocks.push block
    r = __proc_block_call(*args)
    @@blocks.pop
    r
  end

  def [](*args, &block)
    @@blocks.push block
    r = __proc_block_indexer(*args)
    @@blocks.pop
    r
  end
end


module Kernel
  def pyield(*args)
    Proc.yield(*args)
  end

  def pblock_given?
    Proc.block_given?
  end
end
--- code ---

I still don't know why I can't use a block with the normal use of
[]... is that going to ever change?

I know I can do obj.send(:[], *args) or obj.[](*args) -- but I think
we all know using obj[*args] is best!  :-)

~Me!

-- 
There's no word in the English language for what you do to a dead
thing to make it stop chasing you.


0
ummaycoc (52)
8/6/2004 12:54:54 AM
Matt Maycock <ummaycoc@gmail.com> writes:

[snip code]

If I understand what you're trying to do, the latest (CVS) ruby allows
blocks to take blocks.

irb(main):001:0> lammy = lambda{|&b| b.call}
=> #<Proc:0x402145f8@(irb):1>
irb(main):002:0> lammy.call{10}
=> 10
irb(main):003:0> 

> I still don't know why I can't use a block with the normal use of
> []... is that going to ever change?
>
> I know I can do obj.send(:[], *args) or obj.[](*args) -- but I think
> we all know using obj[*args] is best!  :-)

I don't know if it will change or not.  I'm somewhat impartial to it,
though.  I always thought the rationale for Proc#[] was not for saving
keystrokes, nor for kludging a #() operator, but rather to allow a
compact representation of a procedurally generated collection.  E.g.,
instead of explicitly using an array of the numbers [0, 2, 4, ...,
something_big], you can just use lambda{|x| 2*x}.  These sorts of uses
generally have no business taking blocks.

I could of course be wrong, though.
0
g_ogata (135)
8/6/2004 1:33:47 AM
> If I understand what you're trying to do, the latest (CVS) ruby allows
> blocks to take blocks.
> 
> irb(main):001:0> lammy = lambda{|&b| b.call}
> => #<Proc:0x402145f8@(irb):1>
> irb(main):002:0> lammy.call{10}
> => 10
> irb(main):003:0>

Neato!


> I don't know if it will change or not.  I'm somewhat impartial to it,
> though.  I always thought the rationale for Proc#[] was not for saving
> keystrokes, nor for kludging a #() operator, but rather to allow a
> compact representation of a procedurally generated collection.  E.g.,
> instead of explicitly using an array of the numbers [0, 2, 4, ...,
> something_big], you can just use lambda{|x| 2*x}.  These sorts of uses
> generally have no business taking blocks.
> 
> I could of course be wrong, though.

I could imagine some uses for it taking a block... like the block
being a test for whether to use the current attempted return value, or
try to generate another...


0
ummaycoc (52)
8/6/2004 4:04:12 PM
Reply: