Forum: Ruby Global not evaluated properly in 'if' statement modifier

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
0cb023654f46a6bd171405af6419baf6?d=identicon&s=25 darren kirby (Guest)
on 2006-06-10 20:16
(Received via mailing list)
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
31af45939fec7e3c4ed8a798c0bd9b1a?d=identicon&s=25 Matthew Smillie (notmatt)
on 2006-06-10 20:59
(Received via mailing list)
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
0cb023654f46a6bd171405af6419baf6?d=identicon&s=25 darren kirby (Guest)
on 2006-06-10 20:59
(Received via mailing list)
quoth the darren kirby:
> Hello all,
>
> I am scratching my head over this one.
> I have a method:

<snip>

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
04bd97396a23bebf19887fd041e15123?d=identicon&s=25 Esteban Manchado =?iso-8859-1?Q?Vel=E1zquez?= (Guest)
on 2006-06-10 21:12
(Received via mailing list)
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,
0cb023654f46a6bd171405af6419baf6?d=identicon&s=25 darren kirby (Guest)
on 2006-06-10 21:56
(Received via mailing list)
quoth the Esteban Manchado Velázquez:
> Hi Darren,

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

<snip>
>
>     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
0cb023654f46a6bd171405af6419baf6?d=identicon&s=25 darren kirby (Guest)
on 2006-06-10 21:56
(Received via mailing list)
quoth the Matthew Smillie:
>
> 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
This topic is locked and can not be replied to.