问题
I am trying to write a method in Ruby that uses a here-document of HTML code with input variables and fills them in accordingly.
My method is:
calcForm(left, op, right, result)
The html tags I am using are
<input type="text" name="left" value="?????">
<select name="op">
<option value="add" ?????>+</option>
<option value="mul" ?????>*</option>
</select>
<input type="text" name="right" value="?????">
=
?????
Everywhere there are question marks my method has to fill in with variables left, op, right, and result.
For example,
calcForm(6, "mul", 7, 42)
should return the string:
<input type="text" name="left" value="**6**">
<select name="op">
<option value="add">+</option>
<option value="mul" **selected**>*</option>
</select>
<input type="text" name="right" value="**7**">
=
**42**
So, the word "selected" should appear after "add" or "jul" depending on the value of op, the values of left and right should be filled in in value = "...", and the result should appear on the last line.
I am new to ruby but this is what I have done so far with my knowledge of here docs:
the_tags = <<HERE
<input type="text" name="left" value=#{left}>
<select name="op">
<option value="add" #{op}>+</option>
<option value="mul" #{op}>*</option>
</select>
<input type="text" name="right" value=#{right}>
=
#{result}
HERE
def calcForm(left,op,right,result)
I am stuck at this point. I am confused at how to connect my method calcForm to the here document above.
Any help with this would be greatly appreciated!
Thank you!
回答1:
It looks like you're thinking of a heredoc as a sort of template, that you define once, with string interpolations built in, and then reuse. It isn't. As with any string definition, the string interpolation happens on the fly when the variable is defined.
So you would just do
def calcForm(left,op,right,result)
<<HERE
<input type="text" name="left" value=#{left}>
<select name="op">
<option value="add" #{op}>+</option>
<option value="mul" #{op}>*</option>
</select>
<input type="text" name="right" value=#{right}>
=
#{result}
HERE
end
However, a better approach for what you're trying to do might be ERB, which works more like what you had in mind above; i.e. it is a template.
require 'erb'
template = ERB.new <<HERE
<input type="text" name="left" value=<%=left%>>
<select name="op">
<option value="add" <%=op%>>+</option>
<option value="mul" <%=op%>>*</option>
</select>
<input type="text" name="right" value=<%=right%>>
=
<%=result%>
HERE
def calcForm(left,op,right,result)
template.result(binding)
end
Note that binding
here is a magic word that means "evaluate the expression in the current context"; i.e. with the currently defined variables (the parameters that were passed in).
回答2:
The easiest answer is to define and return the string inside your method, and use the parameter names as the interpolation variables.
回答3:
This should work:
def calcForm(left,op,right,result)
<<HERE
<input type="text" name="left" value="#{left}">
<select name="op">
<option value="add" #{'selected' if op == 'add'}>+</option>
<option value="mul" #{'selected' if op == 'mul'}>*</option>
</select>
<input type="text" name="right" value="#{right}">
=
#{result}
HERE
end
I added some quotes around your attributes to help with HTML validation. You don't need to explicitly write return
or declare a local variable because the return value of the method will always be the value of the last ruby expression.
来源:https://stackoverflow.com/questions/8131536/ruby-here-documents