block variable not working how I expect it to work

J

James Dinkel

Here is my ruby version:
ruby 1.8.6 (2007-09-24 patchlevel 111) [i386-mswin32]

Here is the block I wrote (this is actually a little test block for
testing part of a larger block):
------------
def myblock
testvar = ['cool', ' array']
yield testvar
print testvar
end
------------

Now here is a snippet of code that isn't giving the result I would
expect:
------------
myblock do |stuff|
stuff = 'dumb string'
end
------------

This outputs "cool array" when I would expect it to output "dumb string"
since I changed the variable when executing the block. So my question
is: how can I get 'testvar' to change to whatever the end result of
'stuff' is when the block executes?

Thanks,

James Dinkel
 
M

Martin DeMello

Here is my ruby version:
ruby 1.8.6 (2007-09-24 patchlevel 111) [i386-mswin32]

Here is the block I wrote (this is actually a little test block for
testing part of a larger block):
------------
def myblock
testvar = ['cool', ' array']
yield testvar
print testvar
end
------------

Now here is a snippet of code that isn't giving the result I would
expect:
------------
myblock do |stuff|
stuff = 'dumb string'
end
------------

This outputs "cool array" when I would expect it to output "dumb string"
since I changed the variable when executing the block. So my question
is: how can I get 'testvar' to change to whatever the end result of
'stuff' is when the block executes?

In ruby, variables are just labels pasted onto objects. What gets
passed around are the objects themselves, but the = operator pastes
the variable onto a new object. So when you say
yield testvar

you're passing the *object* testvar is currently labelling to the
block. When you say
myblock do |stuff|

myblock receives the object and pastes the label 'stuff' on it. Then
when you say
stuff = 'dumb string'

you are creating a new object, 'dumb string', removing the 'stuff'
label from the original object, and pasting it onto your new object.
Back in 'myblock', of course, 'testvar' is still pasted on the
original object, and won't have changed. What you essentially want to
do is remove the variable 'testvar' from the first object and paste it
onto something else that you obtain from the block. To do that, you'll
need to use the *return value* of the block, not any of its variable
assignments. Therefore your code should be:

def myblock
testvar = ['cool', 'array']
testvar = yield testvar
print testvar
end

myblock do |stuff|
return "dumb string"
end

martin
 
K

Karl von Laudermann

Therefore your code should be:

 def myblock
    testvar = ['cool', 'array']
    testvar = yield testvar
    print testvar
 end

  myblock do |stuff|
    return "dumb string"
  end

I was going to post a response similar to yours but you beat me to it.
However, I tried your version, and the return statement is causing an
error. You instead just want to do:

myblock do |stuff|
"dumb string"
end
 
J

James Dinkel

Martin said:

Wow, I couldn't have asked for a better explanation. I *suspected* I
may have to do something like "testvar = yield testvar" but it didn't
make any sense why I couldn't just edit the variable directly. Now I
know. Thanks!

James
 
M

Martin DeMello

Therefore your code should be:

def myblock
testvar = ['cool', 'array']
testvar = yield testvar
print testvar
end

myblock do |stuff|
return "dumb string"
end

I was going to post a response similar to yours but you beat me to it.
However, I tried your version, and the return statement is causing an
error. You instead just want to do:

myblock do |stuff|
"dumb string"
end

oops, yes - that'll teach me to type code straight into email. been
doing too much javascript of late!

martin
 

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

Forum statistics

Threads
473,989
Messages
2,570,207
Members
46,783
Latest member
RickeyDort

Latest Threads

Top