I’ve been working on a templating engine recently and had the need to substitute some variables on the page with the result of an slightly expensive remote API call. The first iteration was just a simple replace on the page:
render_placeholder result,
"some_page_var",
ApiWrapper.some_expensive_call
def render_placeholder result, name, value
result.gsub! name, value
end
This “worked” but the problem is the call would be made even if the variable that needed replacing wasn’t on the page. The easy fix is to check it exists before making the substitution:
render_placeholder(result,
"some_page_var",
ApiWrapper.some_expensive_call) if has_placeholder?(result, "some_page_var")
def has_placeholder? result, name
!!result[name]
end
def render_placeholder result, name, value
result.gsub! name, value
end
While this works, once you have a load of results you want to replace there ends up being a lot of duplication, and it’s easy to check the wrong variable compared to what you want to replace. One way to solve it is by passing the api call as a block to the substitution method. This way we can tidy up the code:
render_placeholder(result, "some_page_var") { ApiWrapper.some_expensive_call }
def has_placeholder? result, name
!!result[name]
end
def render_placeholder result, name
return "" unless has_placeholder?(result, name)
result.gsub! name", yield
end