Build an array using data from an exisiting array

S

Sean Warburton

I'm buiding a script at the moment and part of it receives a trigger via
Telnet to say send me an XML request for one of five random items.

Sending the request is time critical, so the faster the better and what
I do at the moment is wait for the trigger command and only then
populate the XML with the correct match from the array of five items.

It does work but what I'd like to do is pre-build an array of the five
possible files so that when I get the trigger I can just send the
correct file.

I'm a total newbie and I can't find how to build an array of XML files
using the data from an existing array to populate the files.

Am I making sense? If I am could someone offer me some pointers on how
to build an array using the data from an existing array.
 
B

burke

How about something like:

file_names = ["a.xml", "b.xml", "c.xml", "d.xml", "e.xml"]
file_contentses = file_names.map{|file| File.read(file)}


so now you can do `file_contentses[0]`, for example, to get the
contents of a.xml.
 
S

Sean Warburton

burke said:
How about something like:

file_names = ["a.xml", "b.xml", "c.xml", "d.xml", "e.xml"]
file_contentses = file_names.map{|file| File.read(file)}


so now you can do `file_contentses[0]`, for example, to get the
contents of a.xml.

Hello Burke, thanks for the reply, I used the word file but I don't
actually build a file, sorry. What i should have said is that I want to
build an array of five XML requests , populating each request with the
data from an existing array of five items that will be passed as an
argument. Does that sound clearer and make more sense?

Thanks for your help.
 
R

Robert Klemme

2010/1/27 Sean Warburton said:
burke said:
How about something like:

file_names = ["a.xml", "b.xml", "c.xml", "d.xml", "e.xml"]
file_contentses = file_names.map{|file| File.read(file)}


so now you can do `file_contentses[0]`, for example, to get the
contents of a.xml.

Hello Burke, thanks for the reply, I used the word file but I don't
actually build a file, sorry. What i should have said is that I want to
build an array of five XML requests , populating each request with the
data from an existing array of five items that will be passed as an
argument. Does that sound clearer and make more sense?

Are you looking for something like this?

irb(main):011:0> require 'rexml/document'
=> true
irb(main):012:0> docs = (1..5).map do |i|
irb(main):013:1* d = REXML::Document.new
irb(main):014:1> d.add_element("my_root").text = "item no. #{i}"
irb(main):015:1> d.to_s
irb(main):016:1> end
=> ["<my_root>item no. 1</my_root>", "<my_root>item no. 2</my_root>",
"<my_root>item no. 3</my_root>", "<my_root>item no. 4</my_root>",
"<my_root>item no. 5</my_root>"]
irb(main):017:0> docs[2]
=> "<my_root>item no. 3</my_root>"
irb(main):018:0>

Of course your document construction is likely more complex.

see http://www.germane-software.com/software/rexml/

Kind regards

robert
 
B

Brian Candler

Sean said:
Hello Burke, thanks for the reply, I used the word file but I don't
actually build a file, sorry. What i should have said is that I want to
build an array of five XML requests , populating each request with the
data from an existing array of five items that will be passed as an
argument. Does that sound clearer and make more sense?

# This converts a single item into its XML request
def process(input)
"The answer is #{input}"
end

source = ["foo", "bar", "baz"]

# Option 1: build another array

dest = source.map { |doc| process(doc) }
puts dest[0]

# Option 2: build a Hash

dest = {}
source.each { |doc| dest[doc] = process(doc) }
puts dest["foo"]
 
S

Sean Warburton

Brian said:
# This converts a single item into its XML request
def process(input)
"The answer is #{input}"
end

source = ["foo", "bar", "baz"]

# Option 1: build another array

dest = source.map { |doc| process(doc) }
puts dest[0]

# Option 2: build a Hash

dest = {}
source.each { |doc| dest[doc] = process(doc) }
puts dest["foo"]

Thanks everyone for your replies.

Brian, this seems like what I'm looking for but can I ask a question.
Why if move ...

source.each { |doc| dest[doc] = process(doc) }

above

def process(input)
"The answer is #{input}"
end

rather than below like you have, does it throw the error

undefined local variable or method `source' for #<Object:0xb787294c>
(NameError)

Thanks
 
B

Brian Candler

Sean said:
Why if move ...

source.each { |doc| dest[doc] = process(doc) }

above

def process(input)
"The answer is #{input}"
end

rather than below like you have, does it throw the error

undefined local variable or method `source' for #<Object:0xb787294c>
(NameError)

Because you moved it above this line:

source = ["foo", "bar", "baz"]

which is where 'source' is assigned to.

When a ruby script is run, it is first parsed from top to bottom to
build as syntax tree, and then it is executed.

Because in ruby you never have to declare local variables (no "var foo"
here), the system needs to infer what's a local variable, and what's a
method call. It does this by looking for assignments. From the point of
the assignment statement to the end of the scope, that name is treated
as a local variable.

puts x # raises an error; no method x()

x = 123
puts x # prints 123

if false
y = 99
end
puts y # prints nil (the assignment to y was seen in
# parsing stage, even though it's never executed)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top