[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Re: using Proc and yield

Yukihiro Matsumoto

12/15/2006 3:19:00 PM

Hi,

In message "Re: using Proc and yield"
on Sat, 16 Dec 2006 00:05:19 +0900, Alber Eric <alberthier@yahoo.fr> writes:

|Now I wonder if the following code is valid :
|
|p = Proc.new { yield "hello world" }
|p.call { |i| puts i }

Proc is an objectified block that carries the context at the point.
Since no block is given at the point of Proc.new, it raises
LocalJumpError.

|I belived Proc.call was equivalent to a standard method call, it seems
|I'm wrong :). Did I misunderstand something? Can someone tell me where I
|made a mistake?

No, Proc#call is equivalent of yield.

matz.

4 Answers

Alber Eric

12/15/2006 4:00:00 PM

0

OK, thank you for your quick answer

I will just expose what I'm trying to do : I have four differents
methods that are yielding strings. I want to use one or the other
depending on the context but the rest of the process is the same, so I
wrote something like that

p1 = nil
p2 = nil

# First argument handling
case arg1
when 1
p1 = Proc.new { methodI { |s| yield s } }
when 2
p1 = Proc.new { methodII { |s| yield ("foo-" + s + "-bar") } }
end

# Second argument handling
case arg2
when 3
p2 = Proc.new { methodIII { |s| yield s } }
when 4
p1 = Proc.new { methodIV { |s| yield ("oof-" + s + "-rab") } }
end

p1.call { |i|
p2.call { |j|
process(i)
}
}

What I'm looking for is a sort of function pointer.

Thanks

Eric

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

Alber Eric

12/15/2006 4:24:00 PM

0

At the end, read process(i, j) instead of process(i)

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

Tim Pease

12/15/2006 5:09:00 PM

0

On 12/15/06, Alber Eric <alberthier@yahoo.fr> wrote:
> OK, thank you for your quick answer
>
> I will just expose what I'm trying to do : I have four differents
> methods that are yielding strings. I want to use one or the other
> depending on the context but the rest of the process is the same, so I
> wrote something like that
>
> p1 = nil
> p2 = nil
>
> # First argument handling
> case arg1
> when 1
> p1 = Proc.new { methodI { |s| yield s } }
> when 2
> p1 = Proc.new { methodII { |s| yield ("foo-" + s + "-bar") } }
> end
>
> # Second argument handling
> case arg2
> when 3
> p2 = Proc.new { methodIII { |s| yield s } }
> when 4
> p1 = Proc.new { methodIV { |s| yield ("oof-" + s + "-rab") } }
> end
>
> p1.call { |i|
> p2.call { |j|
> process(i)
> }
> }
>
> What I'm looking for is a sort of function pointer.
>


def p1( arg )
yield arg
end

def p2( arg )
yield arg
end

# First argument handling
case arg1
when 1: nil # p1 already defined correctly
when 2
eval %(
def p1( arg )
yield( "foo-" + arg + "-bar" )
end
)
end

# Second argument handling
case arg2
when 3: nil # p2 already defined correctly
when 4
eval %(
def p1( arg )
yield ("oof-" + arg + "-rab")
end
)
end

p1( arg1 ) do |i|
p2( arg2 ) do |j|
process(i,j)
end
end


No need for function pointers. Just define (or redefine) the methods
as you need them.

Blessings,
TwP

George

12/16/2006 3:31:00 AM

0

On 12/16/06, Alber Eric <alberthier@yahoo.fr> wrote:
> OK, thank you for your quick answer
>
> I will just expose what I'm trying to do : I have four differents
> methods that are yielding strings. I want to use one or the other
> depending on the context but the rest of the process is the same, so I
> wrote something like that
>
> [...]
>
> What I'm looking for is a sort of function pointer.

Hi Eric,

Blocks can't take blocks in 1.8, so I think you'll need to resort
to methods if you do it this way. Example:

def methodI_foo_bar
methodI{|s| yield "foo-#{s}-bar"}
end
def methodIII_oof_rab
methodIII{|s| yield "oof-#{s}-rab"}
end

# First argument handling
case arg1
when 1
p1 = method(:methodI)
when 2
p1 = method(:methodI_foo_bar)
end

# Second argument handling
case arg2
when 3
p2 = method(:methodIII)
when 4
p2 = method(:methodIII_oof_rab)
end

p1.call { |i|
p2.call { |j|
process(i, j)
}
}

Or, perhaps more idiomatically:

def methodI_foo_bar
methodI{|s| yield "foo-#{s}-bar"}
end
def methodIII_oof_rab
methodIII{|s| yield "oof-#{s}-rab"}
end

# First argument handling
case arg1
when 1
m1 = :methodI
when 2
m1 = :methodI_foo_bar
end

# Second argument handling
case arg2
when 3
m2 = :methodIII
when 4
m2 = :methodIII_oof_rab
end

send(m1) { |i|
send(m2) { |j|
process(i, j)
}
}

Does that help?