Functions in a loop over string array usually returns nothing

I’m not sure the best way to summarize this (hence the bad title), but I have a list of directions (a string array) and I want to do something with them. First I make a function to generate the list

function list_dirs()
    return filter(x-> isdir(x) && ! occursin(r"^\.",x), readdir())
end

Note that have return in there does not seem to make any difference (I guess Julia can infer what I want?). If I then execute

for directory in list_dirs()
    cd(pwd,directory)
    println("it ran")
end

I get a bunch of “it ran” and nothing else. However cd.(pwd,list_dirs()) works as expected. Also length(list_dirs()) makes sense. typeof(list_dirs()) is also outputing Array{String,1} as expected. Also cd(pwd,list_dirs()[1]) works.

To make things stranger (at least for me),

for directory in list_dirs()
    println(directory)
end

prints the array elements. However this is the only function that seems to be able to act on the array. Trying to instead loop over dir_list = list_dirs() doesn’t help.

To me it feels like I’m missing something fundamental. If I had to guess, I’d say it’s an issue of scope. This is especially frustrating since I recently wrote another script which loops over a file list and operates on the elements in that list.

1 Like

pwd() returns a string, rather than actually printing the working directory. Since for loops return nothing, you don’t get to see that string unless you explicitly print it. Try this:

for directory in list_dirs()
    cd(println ∘ pwd, directory)
end
2 Likes

Right, the last expression in a function is automatically returned. Using the return keyword at the end of a function is optional, since it doesn’t change the behavior of the function at all. The return keyword is only necessary if you want to return early, as in:

function foo()
  if something()
    return
  end
  do_something_else()
end
4 Likes

Thanks, I feel really stupid now, but that was a good lesson so I also feel less stupid than before.

I tend to proto-type everything in the REPL using basic commands (I’m pretty sure that’s normal). In this case had I just run what I wanted in the first place it would have worked.

Julia can really do some nice things with scripting. Not that I need to tell anyone (just about everyone is more familiar with Julia than I am).

@rdeits

Thanks for clearing that up. That makes sense. I guess I’m overly used to explicitly declaring what needs to be returned. Kind of like how after 4 years I’m still uncomfortable writing n = 1 rather than Int64 n = 1.

1 Like