Incrementing variable names in a loop?

M

Matt Brooks

I have a function write_log that takes in a string and it prints to
console and to a logger.

I need to loop through all variables found in an index of an array as a
hash and print them. This list of variables to iterate through is of
variable length(num_bins). The list has variable names(hash keys) that
were created by incrementing the number at the end of the variable name.

There is a little more to the problem in the fact that the signals array
contains objects which have a method_missing defined to handle these
variables by looking them up in a hash. So when signals[0].bin_0 is
called, it looks in the object of the first index of the signals array
for a method called bin_0, it doesn't exist, so I defined the code in
the method_missing method to simply look up that name, bin_0, in a hash
and return that value.


Problem is when I create this variable with an incrementing name, I
can't seem to append it to the end of the signals[0], because I can't do
#{} with another #{} inside of it. I would like this:
write_log("Bin_\##{index}: #{signals[0].#{variable}}")

How can I accomplish this?! Dereference a variable within a variable
that is being dereferenced.


index = 0
while index < num_bins
variable = "bin_#{index}".to_sym
write_log("Bin_\##{index}: #{signals[0].#{variable}}")
index += 1
end


SHOULD:
create calls to
signals[0].bin_0
signals[0].bin_1
signals[0].bin_2 etc until num_bins reached...


Thanks a lot for your help,
Matt
 
J

Jesús Gabriel y Galán

index =3D 0
while index < num_bins
=A0variable =3D "bin_#{index}".to_sym
=A0write_log("Bin_\##{index}: #{signals[0].#{variable}}")
=A0index +=3D 1
end


SHOULD:
create calls to
signals[0].bin_0
signals[0].bin_1
signals[0].bin_2 etc until num_bins reached...

One way:

num_bins.times do |index|
value =3D signals[0].send("bin_#{index}")
write_log("Bin_\##{index}: #{value})
end

Jesus.
 
P

Paul Smith

Problem is when I create this variable with an incrementing name, I
can't seem to append it to the end of the signals[0], because I can't do
#{} with another #{} inside of it. I would like this:
write_log("Bin_\##{index}: #{signals[0].#{variable}}")

write_log("Bin_\##{index}: #{signals[0] + variable}")

Or just

call = signals[0] + variable
write_log("Bin_\##{index}: #{call}")
 
J

Jesús Gabriel y Galán

Problem is when I create this variable with an incrementing name, I
can't seem to append it to the end of the signals[0], because I can't do
#{} with another #{} inside of it. I would like this:
write_log("Bin_\##{index}: #{signals[0].#{variable}}")

write_log("Bin_\##{index}: #{signals[0] + variable}")

Or just

call = signals[0] + variable
write_log("Bin_\##{index}: #{call}")

I might have misunderstood, but I think this doesn't do what the OP
wanted: to *call* the methods named bin_0, bin_1, etc on the
signals[0] object.

Jesus.
 
P

Paul Smith

2009/9/21 Jes=FAs Gabriel y Gal=E1n said:
Problem is when I create this variable with an incrementing name, I
can't seem to append it to the end of the signals[0], because I can't d= o
#{} with another #{} inside of it. I would like this:
write_log("Bin_\##{index}: #{signals[0].#{variable}}")

write_log("Bin_\##{index}: #{signals[0] + variable}")

Or just

call =3D signals[0] + variable
write_log("Bin_\##{index}: #{call}")

I might have misunderstood, but I think this doesn't do what the OP
wanted: to *call* the methods named bin_0, bin_1, etc on the
signals[0] object.

I think I misunderstood. I was focussing too hard on the #{} inside a
#{} problem.



--=20
Paul Smith
http://www.nomadicfun.co.uk

(e-mail address removed)
 
M

Matt Brooks

So I guess technically the way to phrase it is, incrementing method
names... my bad.

Also, I tried both ways, neither seemed to work... It just outputs
nothing, and there is not even an error, I tried to catch an error and
there wasn't one, the output just says pan_data_bin_0 through
pan_data_bin_49, without any data after the colon.

Excuse the calls from object to object, I got tired of stripping the
code. framework object creates a binary object that has an array
created...

I think we are on the right track though...Did I implement one of these
incorrectly?


framework.binary.pan_data_signals[index_pan_data_signal].num_bins.times
do |bin_number_index|
value =
framework.binary.pan_data_signals[index_pan_data_signal].send("bin_#{bin_number_index}")
framework.write_log("Pan Data Bin_\##{bin_number_index}: #{value}")
end



bin_number_index = 0
while bin_number_index <
framework.binary.pan_data_signals[index_pan_data_signal].num_bins
pan_data_variable = "pan_data_bin_#{bin_number_index}".to_sym
call = framework.binary.pan_data_signals[index_pan_data_signal] +
pan_data_variable
framework.write_log("Pan Data Bin_\##{bin_number_index}: #{call}")
bin_number_index += 1
end
 
M

Matt Brooks

Nevermind, I implemented jesus's incorrectly, it works!

I needed the .to_sym from the created method name....

framework.binary.pan_data_signals[index_pan_data_signal].num_bins.times
do |bin_number_index|
pan_data_variable =
"pan_data_bin_#{bin_number_index}".to_sym
value =
framework.binary.pan_data_signals[index_pan_data_signal].send(pan_data_variable)
framework.write_log("Pan Data Bin_\##{bin_number_index}:
#{value}")
end


Thank you a lot to both of you, I was at a lost, and now it works like a
charm!!!
 
J

Jesús Gabriel y Galán

So I guess technically the way to phrase it is, incrementing method
names... my bad.

Also, I tried both ways, neither seemed to work... It just outputs
nothing, and there is not even an error, I tried to catch an error and
there wasn't one, the output just says pan_data_bin_0 through
pan_data_bin_49, without any data after the colon.

Excuse the calls from object to object, I got tired of stripping the
code. =A0framework object creates a binary object that has an array
created...

I think we are on the right track though...Did I implement one of these
incorrectly?


framework.binary.pan_data_signals[index_pan_data_signal].num_bins.times
do |bin_number_index|
=A0 value =3D
framework.binary.pan_data_signals[index_pan_data_signal].send("bin_#{bin_= number_index}")
=A0 framework.write_log("Pan Data Bin_\##{bin_number_index}: #{value}")
end

Looks good. Check this:

irb(main):032:0> class BinarySignal
irb(main):033:1> def bin_0
irb(main):034:2> "bin_0_data"
irb(main):035:2> end
irb(main):036:1> def bin_1
irb(main):037:2> "bin_1_data"
irb(main):038:2> end
irb(main):039:1> def bin_2
irb(main):040:2> "bin_2_data"
irb(main):041:2> end
irb(main):042:1> end
irb(main):046:0> bin =3D BinarySignal.new
=3D> #<BinarySignal:0xb7dcc5a0>

irb(main):056:0> 3.times do |index|
irb(main):057:1* puts "Bin data \##{index}: #{bin.send("bin_#{index}")}"
irb(main):058:1> end
Bin data #0: bin_0_data
Bin data #1: bin_1_data
Bin data #2: bin_2_data


So I assume that some assumption is incorrect. Can you put some traces ther=
e?
p framework.binary.pan_data_signals[index_pan_data_signal]

Are you sure that object responds to bin_xxx and returns something
that is printable?
If you are handling those calls with method missing and looking in a
Hash, maybe the hash is empty for that key, returning nil, and that's
why we see nothing:

irb(main):059:0> class BinarySignal
irb(main):060:1> def bin_0
irb(main):061:2> nil
irb(main):062:2> end
irb(main):063:1> def bin_1
irb(main):064:2> nil
irb(main):065:2> end
irb(main):066:1> def bin_2
irb(main):067:2> nil
irb(main):068:2> end
irb(main):069:1> end
=3D> nil
irb(main):070:0> bin =3D BinarySignal.new
=3D> #<BinarySignal:0xb7df3b8c>
irb(main):071:0> 3.times do |index|
irb(main):072:1* puts "Bin data \##{index}: #{bin.send("bin_#{index}")}"
irb(main):073:1> end
Bin data #0:
Bin data #1:
Bin data #2:

If I were you I would try to make sure that internal hash is correctly
filled for that object. Maybe print it also before the loop, to see
what's inside.

Jesus.
 
J

Jesús Gabriel y Galán

Nevermind, I implemented jesus's incorrectly, it works!

I needed the .to_sym from the created method name....

=A0 =A0 =A0 =A0 =A0 =A0framework.binary.pan_data_signals[index_pan_data_s= ignal].num_bins.times
do |bin_number_index|
=A0 =A0 =A0 =A0 =A0 =A0pan_data_variable =3D
"pan_data_bin_#{bin_number_index}".to_sym
=A0 =A0 =A0 =A0 =A0 =A0value =3D
framework.binary.pan_data_signals[index_pan_data_signal].send(pan_data_va= riable)
=A0 =A0 =A0 =A0 =A0 =A0framework.write_log("Pan Data Bin_\##{bin_number_i= ndex}:
#{value}")
=A0 =A0 =A0 =A0 =A0end


Thank you a lot to both of you, I was at a lost, and now it works like a
charm!!!

OK. I had already answered in another thread (it appeared as another
thread in my email client) before noticing this.
Strange though, because send works with strings too. See my examples
in the other thread or this one:

irb(main):074:0> "abcde".send("size")
=3D> 5

Jesus.
 
M

Matt Brooks

Thanks a lot for your detailed breakdown in the earlier post. I had
already verified I could print them one by one by explicitly say
xxx.bin_0 etc... but I understood what you were saying...


I think it might have something to do with putting it within an existing
#{} that made it work!? Not sure why this works and the earlier
didn't...

framework.binary.pan_data_signals[index_pan_data_signal].num_bins.times
do |bin_number_index|
framework.write_log("Pan Data Bin_\##{bin_number_index}:
#{framework.binary.pan_data_signals[index_pan_data_signal].send("pan_data_bin_#{bin_number_index}")}")
end



This below, didn't work earlier...

framework.binary.pan_data_signals[index_pan_data_signal].num_bins.times
do |bin_number_index|
value =
framework.binary.pan_data_signals[index_pan_data_signal].send("bin_#{bin_number_index}")
framework.write_log("Pan Data Bin_\##{bin_number_index}: #{value}")
end


Thanks again
Matt
 

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,981
Messages
2,570,188
Members
46,731
Latest member
MarcyGipso

Latest Threads

Top