0

I am iterating through this_dir,

this_dir = Dir.new(".") 

putsing each .rb file. With the folders (everything that aren't .rb), I would like to open them, list their contents, and set them to a variable. I created an array names to get the variable name from, and planned to iterate through it by calling it with names_index and adding 1 to that.

names = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'n', 'm', 'o', 'p'] names_index = 0 

Unfortunately, the closest thing I know how to do with Array values is puts them, which makes it a string.

this_dir.each do |file| if file.include?("*.rb") puts file else .... end end 

How do I turn the array values into variable names?

5
  • file.include?("*.rb") will only be true for the literal string '*.rb'. You need to put the wildcard in Dir#glob, as @Jordan has done. You have made no reference to names or name_index after defining those variables. Commented Aug 30, 2015 at 23:56
  • I missed how you were using names. Commented Aug 31, 2015 at 0:04
  • I was going to make reference to names and name_index in the spot where I substituted ..... Unfortunately it wouldn't have had the desired behavior, so I left the dots. I wrote those two variables in my question so that my explanation would be as thorough as possible. Commented Aug 31, 2015 at 0:09
  • 1
    Sorry, I meant file.include?("*.rb") will only be true for filenames that contain the literal string '*.rb'; that is, '*' does not act as a wildcard here. Commented Aug 31, 2015 at 0:15
  • Wow, heheh, nice catch! Commented Aug 31, 2015 at 0:17

2 Answers 2

2

If you just want to list all of the .rb files in a directory and its subdirectories, use Dir.glob with the ** pattern to recurse subdirectories, like so:

Dir.glob('./**/*.rb').each do |file| puts file end 

In general it doesn't make sense to dynamically create variable names for the purpose of storing many items. In such cases (when a better solution like Dir.glob above isn't available) you should just use an Array (or sometimes a Hash).

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

7 Comments

Well, this doesn't do anything with any of /./'s child directories, it just lists the .rb files in /. I'm also interested in setting variable names in the sense that my question asked. Edit: I just re-read this an it sounded snarky; sorry about that. Any clue why it doesn't handle nested directories?
You're mistaken. The very purpose of the ** pattern is to list files in subdirectories recursively. Take a look at the documentation for Dir.glob. The code above will list every .rb file in . and in every subdirectory of . and in every subdirectory of each of those directories ad infinitum.
The only way to set local variables in the way you apparently want to is using eval, e.g. eval("foo = 'bar'"), but there are vanishingly few situations in which that's preferable to another method like (in the case of storing many items) an Array or Hash.
Interesting... the second time I ran code it putsd things exclusively in subdirectories, whereas the first time I ran code it only ran things in the . directory. Not quite sure why the difference, but I'm guessing the behavior on the second try was correct?
As @JVernon notes, for Ruby 1.9+ you can't set local variables. One might expect eval or binding.local_variable_set would, but they don't.
|
1

Jordan already showed you a better way to achieve whatever you're apparently trying to achieve. However, if for some reason you still want to do it the way you asked, I want to point out that this used to be possible back in Ruby 1.8. But for newer versions (as of time of writing this) you can't dynamically create local variables. But you can still achieve something similar using a hash:

names = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'n', 'm', 'o', 'p'] names_index = 0 table = {} this_dir.each do |file| if file.include?("*.rb") puts file else table[names[names_index]] = file names_index += 1 end end 

Now if a file different than .rb is found, it would be stored and you can access it like this:

table['a']

Which would return such file.

There is obviously little to no practical sense in doing this, and you should probably not do it anyway - but there it is for your curiosity.

2 Comments

Yeah I can see why this is not the best way to go now. The logic is pretty though... thanks for the explanation!
"*" in "*.rb" is not a wildcard. Perhaps if file.end_with(".rb").

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.