1

How can use a variable in the name of another variable? Say, I have a number of arrays like this:

g_OS = ['Mac', 'Linux', 'Win']
g_Mac = ['Lion', 'Tiger', 'Jaguar']
g_Linux = ['Slackware', 'RedHat', 'Caldera']
g_Win = [ .... ]

If I do this: g_OS.each {|OS| puts "g_#{OS}[0]"}, it will print 'g_Mac[0]' or 'g_Linux' as a literal string. But what I actually want is to get the first element of the array: g_Mac. How can I do that?

2 Answers 2

6

Generally it's easier just to rearrange your data. Like this, for example.

g_OS = {
  'Mac' => ['Lion', 'Tiger', 'Jaguar'],
  'Linux' => ['Slackware', 'RedHat', 'Caldera'], 
  'Win' => ['Chicago', 'Daytona', 'Longhorn']
}

# list just the OSes

g_OS.keys # => ["Mac", "Linux", "Win"]

# only linuxes
g_OS['Linux'] # => ["Slackware", "RedHat", "Caldera"]

Although it's technically possible to do exactly what you asked, I advise you against it (and will not, therefore, post the code). You seem to be new, so you have lots to learn. Don't learn wrong ways.

Sign up to request clarification or add additional context in comments.

8 Comments

Yes, I'm very new in the "Ruby" business and my knowledge is only limited to writing ERB templates for Puppet. BTW, in the original template, the values for the first array (g_OS in this example) is generated dynamically from a file and so the others as well. Arranging the data the way you suggested probably make it a bit complicated for an ERB template(??). On a separate note, do you mind explaining what wrong with my original approach please?
I was trying follow your suggestion but no such joy yet. So, how do I make a hash of such arrays from a file like this: Slackware, Linux, i-num=1 || Jaguar, Macx, i-num=6 || Chicago, that_Win, i-num=2 || Daytona, this_Win, i-num=7 || RedHat, Linux, i-num=5 || Tiger, Macy, i-num=3 (|| are the line breaks, of course.) Cheers!!
@MacUsers: it's hard to read code in comments. Ask another question.
@MacUsers: as to "why my original approach is bad": referring to local variables by dynamically generating their names is generally a code smell, a sign that you're doing something wrong. I am writing ruby for 5+ years and I have never needed it (there were always better ways).
Completely agree with you: there were always better ways. Added code to my OP as you suggested for better visibility.
|
1

This is to answer to my own question, which completely different compare to my original question, but it serves exactly (well, more or less) the same purpose. So, as Sergio suggested: Say the example input file is something like this:

maci:ruby san$ cat OSs.txt 
Slackware, Linux, i-num=1
Jaguar, MacX, i-num=6
Chicago, this_Win, i-num=2
Daytona, an_other_Win, i-num=7
RedHat, Linux, i-num=5
Lion, MacY, i-num=4
Caldera, Linux, i-num=9
Longhorn, that_Win, i-num=8
Tiger, MacZ, i-num=3
Indiana, Solaris, i-num=10
Kodiak, MacX, i-num=11

The actual file is dynamically created with variable number of OSs i.e. the file may or may not have Mac or Win at all. Taking from there, this is what I came up so far....

inFile = "OSs.txt"
os = {}

open(inFile, 'r').each do |line|
    next if line =~ /^\s*(#|$)/

    if line.split(',').map(&:strip)[1] =~ /^Mac/
        (os[:Mac] ||= []) << line.split(',').map(&:strip)[0]
    end

    if line.split(',').map(&:strip)[1] =~ /_Win$/
        (os[:Win] ||= []) << line.split(',').map(&:strip)[0]
    end

    if line.split(',').map(&:strip)[1] !~ /(^Mac|_Win$)/
        (os[:Linux] ||= []) << line.split(',').map(&:strip)[0]
    end
end

os.each_key do |cls|
    p "%s [%s]" % [os[cls][0], os[cls].count]
end

It's pretty much doing what I actually want but I believe there are a lot better ways of doing it. Cheers!!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.