template toolkit hash values not printing and keys not sorting numerically - template-toolkit

starting with a hash ref....
my $my_hash = {};
building the hash in a loop...
push(#tmp_arr,$val1);
push(#tmp_arr,$val2);
$my_hash->{$index} = \#tmp_arr;
the elements for any key can be access fine as $my_hash->{$index}[0]
I am passing a hash like this:
my $vars = {
myhash => $my_hash
};
PROBLEM 1: trying to print like this, it prints the index correctly but does not print any values.... i am confused why?
[%- FOREACH index IN myhash.keys.sort -%]
<tt>index number=[%index%] value_1=[%myhash.$index.0%] value_2=[%myhash.$index.1%]<tt>
[% END -%]
PROBLEM 2: the sort is not sorting numerically, so i get 1,10,11,12.... 2,20,21.....

The first problem is probably down to confusion over whether $index refers to array position or a hash-key. I'd suspect it is probably assuming that a numeric key belongs to an array.
The vmethod item() is often a useful work-around when you have hash-keys that can be confused with other vmethods. I would try the following:
<tt>index number=[%index%] value_1=[%myhash.item(index).0%]
value_2=[%myhash.item(index).1%]
</tt>
The second problem is easily sorted (if you'll pardon the pun):
[%- FOREACH index IN myhash.keys.nsort -%]
By the way, there's another open <tt> tag at the end of your example, but I assume it's right (a closing </tt>) in your original code.

Related

Avoiding quotes in a map variable

I'm trying to create a query with variables from a map function, but the content stored in one of these fields does contain ' (quotes, like Barney's). So everytime it cracks since the ' will break the statement. How can I get around it?
I tried to use the .split function but no sucess.
No worries about SQL Injection since I'm just loading data from an API to my db.
Code:
query_values = activities.map do |activity|
'(' +
"#{activity['id']},
""'#{activity['type']}""'" #using ""' just to fill the column when empty cells are raised
+')'
end
query = "INSERT INTO pd_activities VALUES #{query_values.join(', ')}"
Thanks in advance.
How to do this properly is listed on the cheat sheet:
db[:pd_activities].insert(
id: activity['id'],
type: activity['type']
)
This takes care of all the escaping issues for you. If all activity has is those two keys you might even be able to do this:
db[:pd_activities].insert(activity)

Ruby REXML: Get Value Of An XML Element

I am trying to put the values of some xml elements into an array using rexml. Here is an example of what I am doing:
doc = Document.new("<data><title>This is one title</title><title>This is another title</title></data>")
XPath.each( doc, "*/title") { |element|
puts element.text
}
However, that outputs:
[<title> ... </>, <title> ... </>]
How can I get it to output an array containing "This is one title" and "This is another title"?
Moving my comment to an answer, per request:
While puts may convert its argument its argument to a string anyway, you can have the XPath return the text node in the first place:
XPath.each(doc, "*/title/text()") {...
Are you sure about that? Here's a complete program:
#!/usr/bin/ruby
require 'rexml/document'
include REXML
doc = Document.new("<data><title>This is one title</title><title>This is another title</title></data>")
XPath.each( doc, "*/title") { |element|
puts element.text
}
Output:
This is one title
This is another title
Edit: It sounds like the OP has moved on, but I think there should be some clarification added here for future visitors. I upvoted #LarsH's good answer, but it should be noted that, given the OP's specific input, element.text should produce exactly the same output as would result from selecting the text() nodes in the first place. From the docs:
text( path = nil )
A convenience method which returns the String value
of the first child text element, if one exists, and nil otherwise.
The sample input given in the original question shows <title> elements containing only one text node in each case. Therefore, these two methods are the same (in this case).
However, pay attention to this important note:
Note that an element may have multiple Text elements, perhaps
separated by other children. Be aware that this method only returns
the first Text node.
You can get all of an element's child text nodes using texts() (plural).
What I suspect a lot of people are really looking for is an equivalent of the DOM's textContent (or its illegitimate cousin innerText). Here's how you might do that in Ruby:
XPath.each(doc, "*/title") { |el|
puts XPath.match(el,'.//text()').join
}
This joins all of the text descendants of each element into a single string.
The short answer is that there's no short answer. Which one of these you want, if any, is highly context-specific. The only requirement in the original question is to "put the values of some xml elements into an array", which isn't really much of a specification.

Lua: attempt to index field '?' (a nil value)

I am just starting with lua, and i have some code, from someone with some intentionally mistakes in it. Now i've hit a roadblock getting this error on and on for the following code:
function SIM_Utils:ClickButton(app, buttonName)
page = app:getTopPage()
widgets = page:getWidgets(buttonName)
print (type(widgets))
print (widgets[1])
widgets[1]:click(true, 5000)--this yields "attempt to index field '?' (a nil value)"
widgets[1]:click(false,0)--this yields "attempt to index field '?' (a nil value)"
app:captureScreen()
end
This will result in:
table
WidgetCommon (09590790)
L.E.
After running what Alex posted here is the result:
widgets=
table: 0A45CF28
1
WidgetCommon (09590790)
Is table: 0A... the answer i am looking for?
L.E. 2: Reposted the whole function since it seems this is where the problem lays
What is page:getWidgets returning? You can check it with print(type(widgets)). If it is a table, then array position 1 is not defined in that table (you can loop through the table contents using the pairs function). If it's not a table, then you're attempting to lookup an index on something that isn't a table, which won't work.
Also, since you're new to Lua, realize that page:getWidgets is not a built-in component. So, you'll need to load this functionality or use the appropriate derived application that provides this function.
Try running the following code:
widgets = page:getWidgets(buttonName)
print("widgets=", widgets) -- Should print out something like "Widgets= 0x12345678". If it doesn't then widgets is nil. In other words nothing is there.
for k, v in pairs(widgets) do
print(k, v)
end
That will make sure you make sure you have a widgets table, and if you do, it'll tell you whats in it. If you don't have anything at an index of 1, then that's your problem: page:getWidgets(buttonName) is not returning a list of widgets like you expect.
It seems unlikely, but it's possible (and it in fact looks like the only possibility from the info you've posted) that the library you're using is throwing the error, not your code. Be aware that when an error is thrown in Lua, the throwing code and tell Lua to show the error as thrown from your calling code, rather than in the Library code. That should only be used for logical errors like "Bad arguments to Widget::show", not something like what you're getting, but it can happen. Also, an error in a C function will show up sort of like it came from your code. EG:
io.open("myFile").read() --> should be ":read", not ".read"
stdin:1: attempt to index a nil value
stack traceback:
stdin:1: in main chunk
[C]: ?
Do you have a stack traceback to show as well as the error?

mapping to value in deep hash

I'm doing an application using mongodb and mongoid and I'm facing a problem where I need to map something in one document to something in another document. My plan is to store something in a document that I can then use to figure out what value for it to fetch from a different collection. But, this is more generally a ruby question about how I can fetch data from deep within a hash.
I have a structure something like this:
Widget
Sections
0
Fields
0
value: foobar
If that makes sense. Let's say I want to get the value of the first field in the first section, I would do something like:
#widget.sections[0].fields[0].value
No problem.
Now the question is, how can I do this with all of that as a string? What I want to do is store within the database a mapping value. So I've have a key/value with something like:
mapping: "sections[0].fields[0].value"
Now how can I use that to get the data from #widget? I've tried #widget.send "sections[0].fields[0].value" but that does not work... I can do #widget.send "sections" and get back an array of sections, but I'm not quite sure how to take it further...
So to summarize, I can do this:
#widget.sections[0].fields[0].value
if I have #widget and a string "sections[0].fields[0].value" how can I execute that?
#widget.instance_eval("sections[0].fields[0].value")
should do the trick.

rails break pasted code into lines and display

Lets say I have a rails application in which code is pasted into the content text box like the following.
Pasted Code
Person name
Person name
Person name
Person name
It is put into the database with the proper new lines after each line according to my server log.
What I want to do is in the show action I want to output this text after removing any blank spaces between names and remove any double names and put them in alphabetical order.
I also want to add an html option tag around them.
I have already written a program in Java to do this using sets. I was wondering how to approach this in rails. I would assume the code to do this would go in the controller.
My second question was in the index action. It shows all the pasted items. How can I only show a snippet of what was actually pasted. Lets say 20 characters long? Thanks!
removing any blank spaces between names
have no idea what 'blank spaces between' means, but I assume you want to remove 'blank lines':
lines = code.split(/\n\r?/).reject { |l| l.strip.empty? }
remove any double names
lines = lines.uniq # or uniq!
put them in alphabetical order
lines = lines.sort # or sort!
add an html option tag around them
options_str = lines.map { |l| "<option value='#{l}'>#{l}</option>" }.join('\n') # Do not forget to escape html
Or if you want it shorter:
code.split(/\n\r?/).reject { |l| l.strip.empty? }.uniq.sort.map do |l|
"<option value='#{l}'>#{l}</option>"
end.join('\n')
That should give you a tip.
The most important thing for you would probably be having String, Array and Enumerable documentation in front of you.

Resources