Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ruby here documents

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!

like image 431
Shabu Avatar asked Feb 22 '26 23:02

Shabu


1 Answers

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).

like image 86
Jacob Mattison Avatar answered Feb 25 '26 11:02

Jacob Mattison