Zoe Phoenix wrote:

> output =
> 30.times do [rand(citylist.length)]

First of all Integer#times returns self, so 30.times will return 30 which 
means that the value of output will be 30.
Second of all rand(foo) returns a number between 0 (inclusive) and foo 
(exclusive). [rand(foo)] will simply return an array containing that number. 
So the value of [rand(citylist.length)] may be [5] or [4], but it will never 
be a city name. Also as you don't do anything with the value the whole thing 
won't have any effect on the result of the program.

>   %Q(<a
> href="http://www.website.com/cities/website#{rand(citylist.length)}.html">W
>ebsite #{rand(citylist.length)}</a> | )
> end

This will create links like "...website1.html", "website5.html" etc. It won't 
contain city names. If you want a random city name you have to do: 
citylist[rand(citylist.length)] which might evaluate to citylist[5] for 
example which will evaluate to a city name.
Also as with the previous array you don't do anything with the string you 
created here (the string will be the return value of the block, but the times 
method doesn't care about the block's return value, so it will be discarded).


> The two instances of the
> city inside the block should be the same, but I'm not sure how to do
> that.

As I explained, there aren't any cities in the block, just numbers. And those
are not the same (except if rand returns the same number twice by coincidence)
If you want to use one random city multiple times do:
city = citylist[rand(citylist.length)]
And then do stuff with city. If you want to remove that city from the list (so 
you won't pick it again when you take another random city), you can use:
city = citylist.delete_at(rand(citylist.length))
So now city might be "miami" and the citylist will no longer contain miami.

> Doesn't rand make it a random city each time it's interpreted or 
> since it's in a block, would it be the same each time the block
> repeats..?

It makes a random number each time it's called.

Here's some code that should work:
output = Array.new(30) do
  city = citylist.delete_at(rand(citylist.length))
  %Q(<a href="http://www.website.com/cities/website#{city}.html">Website
  #{city}</a> | )
end
File.open(filename, 'w') do |f|
    f.write output
end

(Array.new(x) will execute the block x times and store the result of the block 
in the array after each execution)
Or if you don't need the temporary array that creates:
File.open(filename, "w") do |f|
  30.times do
    city = citylist.delete_at(rand(citylist.length))
    f.puts %Q(<a
    href="http://www.website.com/cities/website#{city}.html">Website
    #{city}</a> | )
  end
end

Of course in both solutions citylist will be modified in the process (i.e. the 
30 cities will be removed). If that's a problem you should use Robert's 
solution (which has the upside that it doesn't affect citylist and the 
downside that it sorts the entire list, which might be undesirable if the 
list is considerably larger than 30 entries).

HTH,
Sebastian