Proc as a parameter in a class

  • Thread starter Yannick Turgeon
  • Start date
Y

Yannick Turgeon

Hello all,

I'm currently playing with proc and code block as parameter trying to
learn this aspect. Bellow is some code: three sections. The first one
explain by itself what I whant to do, except that I would like to use
classes. The second is the same in my point of view than the first one
and using a class... but it's now doing what I was expecting. The third
one is working but I don' understand why it should be like this.
Anybody can give me the reason?

Thanks.

Yannick

---------------------------------
##### FIRST SECTION #####
puts "First section"

def fn(text)
return proc{|factor| puts text * factor}
end

f = fn("Joe ")
f.call(3) #It prints "Joe Joe Joe ", as expected.




##### SECOND SECTION #####
puts "Second section"

class Bob
def initialize(factor, &block)
@factor = factor
@action = block
end

def run
@action.call(@factor)
end
end

b = Bob.new(3){f}
b.run #It prints nothing [b.run return the function returned by
fn()]



##### THIRD SECTION #####
puts "Third section"

#Redefine run()
class Bob
def run
@action.call.call(@factor) #Why should I call "call"
twice. Isn't @action supposed to be the function returned by fn()?
end
end

b = Bob.new(3){f}
b.run() #It prints "Joe Joe Joe ".
---------------------------------
 
S

Simon Kröger

Yannick said:
Hello all,

I'm currently playing with proc and code block as parameter trying to
learn this aspect. Bellow is some code: three sections. The first one
explain by itself what I whant to do, except that I would like to use
classes. The second is the same in my point of view than the first one
and using a class... but it's now doing what I was expecting. The third
one is working but I don' understand why it should be like this.
Anybody can give me the reason?

Thanks.

Yannick

---------------------------------
##### FIRST SECTION #####
puts "First section"

def fn(text)
return proc{|factor| puts text * factor}
end

f = fn("Joe ")
f.call(3) #It prints "Joe Joe Joe ", as expected.




##### SECOND SECTION #####
puts "Second section"

class Bob
def initialize(factor, &block)
@factor = factor
@action = block
end

def run
@action.call(@factor)
end
end

b = Bob.new(3){f}
b.run #It prints nothing [b.run return the function returned by
fn()]



##### THIRD SECTION #####
puts "Third section"

#Redefine run()
class Bob
def run
@action.call.call(@factor) #Why should I call "call"
twice. Isn't @action supposed to be the function returned by fn()?
end
end

b = Bob.new(3){f}
b.run() #It prints "Joe Joe Joe ".

@action is the block.
@action.call excutes the block which returns f
f.call prints "Joe Joe Joe "

cheers

Simon
 
R

Robert Klemme

Simon said:
Yannick said:
Hello all,

I'm currently playing with proc and code block as parameter trying to
learn this aspect. Bellow is some code: three sections. The first one
explain by itself what I whant to do, except that I would like to use
classes. The second is the same in my point of view than the first
one and using a class... but it's now doing what I was expecting.
The third one is working but I don' understand why it should be like
this. Anybody can give me the reason?

Thanks.

Yannick

---------------------------------
##### FIRST SECTION #####
puts "First section"

def fn(text)
return proc{|factor| puts text * factor}
end

f = fn("Joe ")
f.call(3) #It prints "Joe Joe Joe ", as expected.




##### SECOND SECTION #####
puts "Second section"

class Bob
def initialize(factor, &block)
@factor = factor
@action = block
end

def run
@action.call(@factor)
end
end

b = Bob.new(3){f}
b.run #It prints nothing [b.run return the function returned
by fn()]



##### THIRD SECTION #####
puts "Third section"

#Redefine run()
class Bob
def run
@action.call.call(@factor) #Why should I call "call"
twice. Isn't @action supposed to be the function returned by fn()?
end
end

b = Bob.new(3){f}
b.run() #It prints "Joe Joe Joe ".

@action is the block.
@action.call excutes the block which returns f
f.call prints "Joe Joe Joe "

cheers

Simon

Here's another variant: the proc is reconverted to a block:

##### SECOND SECTION #####
puts "Second section"

class Bob
def initialize(factor, &block)
@factor = factor
@action = block
end

def run
@action.call(@factor)
end
end

# note the end of next line
b = Bob.new(3, &f)
b.run #It prints nothing [b.run return the function returned by
fn()]

Kind regards

robert
 
Y

Yukihiro Matsumoto

Hi,

In message "Re: Proc as a parameter in a class"

|---------------------------------
|##### FIRST SECTION #####
|puts "First section"
|
|def fn(text)
| return proc{|factor| puts text * factor}
|end
|
|f = fn("Joe ")
|f.call(3) #It prints "Joe Joe Joe ", as expected.

|##### SECOND SECTION #####
|puts "Second section"
|
|class Bob
| def initialize(factor, &block)
| @factor = factor
| @action = block
| end
|
| def run
| @action.call(@factor)
| end
|end
|
|b = Bob.new(3){f}
|b.run #It prints nothing [b.run return the function returned by fn()]

Just because you've specified so. @action is {f} which means if you
call, it evaluates the variable reference f and gives you its value.

|##### THIRD SECTION #####
|puts "Third section"
|
|#Redefine run()
|class Bob
| def run
| @action.call.call(@factor) #Why should I call "call" twice. Isn't @action supposed to be the function returned by fn()?
| end
|end
|
|b = Bob.new(3){f}
|b.run() #It prints "Joe Joe Joe ".

Just because you've specified so. Since @action is {f} as above, the
first "call" gives you f, you have to call it again to invoke the f
"function".

matz.
 
Y

Yannick Turgeon

Yukihiro Matsumoto a écrit :
Just because you've specified so. @action is {f} which means if you
call, it evaluates the variable reference f and gives you its value.

Ok! @action is {f} and not f. Everything is clear now. Thank you very
much for your help.

Yannick
 
Y

Yannick Turgeon

Robert Klemme a écrit :
Here's another variant: the proc is reconverted to a block:

# note the end of next line
b = Bob.new(3, &f)
b.run

Interesting. So the "&" convert a proc to a block. So can I conclude
that there is no way to use:
b = Bob.new(3){<some code here>}
to pass fn returned value (a proc) as a block parameter to Bob.new.
You're way is the only way?

Yannick
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,773
Messages
2,569,594
Members
45,122
Latest member
VinayKumarNevatia_
Top