Global not evaluated properly in 'if' statement modifier

Hello all,

I am scratching my head over this one.
I have a method:

def dispatchFile(file)
song = Convert.new(file)
case type
when ‘ogg’
song.oggToWav
song.wavToOgg if $outtype == ‘ogg’
song.wavToMp3 if $outtype == ‘mp3’
song.wavToM4b if $outtype == ‘m4b’
song.wavToFlac if $outtype == ‘flac’
when ‘mp3’
<etc…>
end
end

When I run this code the 'if’s are never evaluated. That is, I have
printed
$outtype, and it has a valid value, but the second method which matches
the
value never runs. If I comment out the ‘if’ and run the two methods
manually
it works fine.

In my tests $outtype’s value is ‘mp3’, so why doesn’t song.wavToMp3 run?
What am I missing?

Thanks for consideration,
-d

quoth the darren kirby:

Hello all,

I am scratching my head over this one.
I have a method:

Well, nevermind. It is sorted.
The docs for GetOptLong have usage examples like so:
value = arg.inspect

So I got rid of the ‘inspect’ and now it works.

-d

On Jun 10, 2006, at 19:13, darren kirby wrote:

song.wavToOgg  if $outtype == 'ogg'

$outtype, and it has a valid value, but the second method which
matches the
value never runs. If I comment out the ‘if’ and run the two methods
manually
it works fine.

In my tests $outtype’s value is ‘mp3’, so why doesn’t song.wavToMp3
run?
What am I missing?

I’m not able to generalise this result, my similar code (at bottom)
works as it should.

So, at a guess, I’d suggest that $outtype is not actually “mp3” but
is “mp3\n”. #puts is smart enough not to include an extra \n, and if
you’re using #print, then the extra line break may not be obvious,
since it would look just like the result of #puts. Similarly, "mp3 "
wouldn’t display as obviously wrong.

For example:

irb(main):020:0> foo = “mp3\n”
irb(main):021:0> puts foo.inspect
“mp3\n”
=> nil
irb(main):022:0> puts foo
mp3
=> nil
irb(main):023:0> foo == ‘mp3’
=> false

If that’s not the case, then I’m stumped.

matthew smillie.

[this code works]

def foobar
type = ‘ogg’
case type
when ‘ogg’
puts “*always”
puts “*ogg” if $outtype == ‘ogg’
puts “*mp3” if $outtype == ‘mp3’
end
end
=> nil
foobar
*always
*mp3
=> nil

quoth the Esteban Manchado Velázquez:

Hi Darren,

Hi,
I did get it sorted but I wanted to respond to your comments…

> > Some suggestions: > > 1) I would calculate the method name dinamically with $outtype, instead > of having 4 if constructions. Something like: > > song.send "wavTo#{$outtype.capitalize}"

Hey, that’s pretty neat. I wondered if there was a way to run the method
based
on “variable variables”. This is certainly more elegant.

2) I wouldn't use a global variable anyway. I think it's better sending

the out type as a parameter.

I have tried this. I guess I don’t fully understand Ruby namespaces, but
$outtype gets it’s value from a command line option, and if I don’t
assign it
to a global then I get:
undefined local variable or method `outtype’ for main:Object (NameError)

It is assigned thusly:

opts.each do |opt, arg|
$outtype = arg if ( opt == ‘–out’ )
[etc…]
end

If I assign to a regular variable ‘outtype’ and then pass it to
dispatchFile():

files.each { |file| dispatchFile(file, outtype) }

I get the undefined variable error, so I guess vars in the do loop are
private, and I don’t know how to use them outside of the loop if they
are not
globals.

3) What is "type", a method? It should probably also be a parameter for

dispatchFile, but I don’t know if that’s a function or a method.

‘type’ is a simple variable that holds the type of infile. So if the
infile is
an ogg, type will be ‘ogg’. It’s value is actually assigned in
dispatchFile
(the method I posted), I just removed a few housekeeping lines to keep
the
code I posted short.

4) Wouldn't it be better having dispatchFile as a Convert method?

Perhaps with other name, but…

I don’t know if this is feasible. It would certainly be a lot of
rewriting to
do it. Convert only accepts 1 file at a time. The way my script works is
to
create an array of files from the command line arguments, then feed one
by
one to dispatchFile, where the proper Convert methods will be run
depending
on the input and output formats. This allows me to just send any file to
Convert and it will Do The Right Thing.

def wavToMp3;  puts "wavToMp3"; end

case type

dispatchFile(‘foo’)
------------------------------------- >8

It printed “oggToWav” and “wavToMp3”. It probably has nothing to do with
global variables not evaluating, but I can’t tell without seeing the rest
of the code.

Regards,

Thanks a lot for your help,
-d

quoth the Matthew S.:

I’m not able to generalise this result, my similar code (at bottom)
works as it should.

So, at a guess, I’d suggest that $outtype is not actually “mp3” but
is “mp3\n”. #puts is smart enough not to include an extra \n, and if
you’re using #print, then the extra line break may not be obvious,
since it would look just like the result of #puts. Similarly, "mp3 "
wouldn’t display as obviously wrong.

Good guess! You were correct even though the bunk value was coming from
outside the code I posted. Thanks!

=> false
case type
=> nil
Thanks again,
-d

Hi Darren,

On Sun, Jun 11, 2006 at 03:13:30AM +0900, darren kirby wrote:

song.wavToOgg  if $outtype == 'ogg'
song.wavToMp3  if $outtype == 'mp3'
song.wavToM4b  if $outtype == 'm4b'
song.wavToFlac if $outtype == 'flac'

when ‘mp3’
<etc…>
end
end

Some suggestions:

1) I would calculate the method name dinamically with $outtype, 

instead of
having 4 if constructions. Something like:

song.send "wavTo#{$outtype.capitalize}"

2) I wouldn't use a global variable anyway. I think it's better 

sending
the out type as a parameter.
3) What is “type”, a method? It should probably also be a parameter
for
dispatchFile, but I don’t know if that’s a function or a method.
4) Wouldn’t it be better having dispatchFile as a Convert method?
Perhaps
with other name, but…

When I run this code the 'if’s are never evaluated. That is, I have printed
$outtype, and it has a valid value, but the second method which matches the
value never runs. If I comment out the ‘if’ and run the two methods manually
it works fine.

In my tests $outtype’s value is ‘mp3’, so why doesn’t song.wavToMp3 run?
What am I missing?

I made a quick test and it worked for me, but I don't know the rest 

of
your code. This is the example that worked:

------------------------------------- 8<

class Convert
def initialize(file); end

def oggToWav;  puts "oggToWav"; end
def wavToOgg;  puts "wavToOgg"; end
def wavToMp3;  puts "wavToMp3"; end
def wavToM4b;  puts "wavToM4b"; end
def wavToFlac; puts "wavToFlac"; end

end

def type; “ogg”; end

$outtype = ‘mp3’

def dispatchFile(file)
song = Convert.new(file)
case type
when ‘ogg’
song.oggToWav
song.wavToOgg if $outtype == ‘ogg’
song.wavToMp3 if $outtype == ‘mp3’
song.wavToM4b if $outtype == ‘m4b’
song.wavToFlac if $outtype == ‘flac’
when ‘mp3’
puts “mp3 nsbb”
end
end

dispatchFile(‘foo’)
------------------------------------- >8

It printed “oggToWav” and “wavToMp3”. It probably has nothing to do
with
global variables not evaluating, but I can’t tell without seeing the
rest of
the code.

Regards,