ruby here documents

a 夏天 提交于 2019-12-05 05:35:33

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!