Un bucle while en un bucle while en Ruby

I'm relativly new to Ruby, or Programming at all, so please excuse me, if i'm making a "noob2 mistake with the logic here.

I am trying to get an output of rgba pixel values in binary for every pixel in an image (and it's location), using Chunky_PNG.

While the output is correct it only displays the first row, seems so as if the outer loop would only run once.

Is there a logical fault in it, or does a while loop in a while loop never work ? That it may be bad practice to do so, i can imagine, but i would still like to know why it doesn't what it's supposed.

require 'chunky_png'
image = ChunkyPNG::Image.from_file('test.png')

#vars
$width0 = 0
$widthmax = image.dimension.width.to_i
$height0 = 0
$heightmax = image.dimension.height.to_i

#main
while $height0 < $heightmax  do
    while $width0 < $widthmax do 
        puts image[$width0,$height0].to_s(2)[0..7] + " " + image[0,0].to_s(2)[8..15] + " " + image[0,0].to_s(2)[16..23] + " " + $height0.to_s + "," + $width0.to_s
        $width0 += 1
    end
    width0 = 0
    $height0 += 1
end

preguntado el 05 de mayo de 13 a las 20:05

Why are you using globals (i.e. variables with a $ prefix) for everything? -

Globals were te first type of variabels used in the tutorial i looked up, so i tought they were the first choice to use -

I'd recommend you find a better tutorial. -

2 Respuestas

Te falta un $

Tiene

width0 = 0

Pero tu quieres

$width0 = 0

This has the effect of never resetting $width0 back to zero, so only the first row is output. It thinks the inner loop never has to run again, since $width0 is still at its maximum value in every iteration after the first one.

(I should probably also add that globals are not the best idea, as others have pointed out, but you did ask for the reason why the script only output the first row. :) )

contestado el 05 de mayo de 13 a las 21:05

Thanks. (a typo, shame on me ...) - x3nu

The error is the missing $ sign as explained by Ray Toal

Even easier it is to to use

each

for the loops. Then you don't need to handle the loop index yourself

($height0..$heightmax).each do |height|
  ($width0..$widthmax).each do |width|
    puts image[width,height].to_s(2)[0..7] + " " + image[0,0].to_s(2)[8..15] + " " + image[0,0].to_s(2)[16..23] + " " + height.to_s + "," + width.to_s
  end
end

contestado el 06 de mayo de 13 a las 00:05

your each variant isn't equivalent since you use inclusive ranges. Since we're indexing from 0, it's even more convenient to use times: heightmax.times {|h| widthmax.times { |w| puts image[w,h]... } } - dbenhur

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.