I want to replace this code
---
myyaml:
me:
:name: "John"
text: |
My name is <% if me %><%= me[:name] %><% end %>
---
With something like this:
---
myyaml:
me:
:name: "John"
text: |
My name is <%=greetings()%>
---
The idea is to define greetings
function outside file and call as result_with_hash
in ERB class.
The desired result is, obviously, My name is John
.
One thing to note is ERB#result_with_hash
states:(emphasis added)
result_with_hash(hash)
Render a template on a new toplevel binding with local variables specified by a Hash object.
So in your case you are trying to call a method greetings()
which is fine and completely accessible but it negates any reason for using result_with_hash
. If you wanted to you could use a local variable greeting
instead and call the method to assign the value.
require 'yaml'
require 'erb'
yaml =<<DOC
---
myyaml:
me:
:name: "John"
text: |
My name is <%=greeting%>
---
DOC
# You used both String and Symbol keys would recommend picking one so this isn't as awkward
name = YAML.load(yaml).dig('myyaml','me',:name)
def greetings(name)
"#{name}!"
end
puts ERB.new(yaml).result_with_hash(greeting: greetings(name))
#=> ---
#myyaml:
# me:
# :name: "John"
# text: |
# My name is John!
#---
The other option would be to just use ERB#result
rather than result_with_hash
. Both result
and result_with_hash
will use the current binding so instance variables, local variables (not overridden by the Hash
provided to result_with_hash
) and methods are all accessible in the ERB
template.
require 'yaml'
require 'erb'
yaml =<<DOC
---
myyaml:
me:
:name: "John"
text: |
My name is <%=greetings()%>
---
DOC
# You used both String and Symbol keys would recommend picking one so this isn't as awkward
@name = YAML.load(yaml).dig('myyaml','me',:name)
def greetings = "#{@name}!"
puts ERB.new(yaml).result
#=> ---
#myyaml:
# me:
# :name: "John"
# text: |
# My name is John!
#---