https://bugs.ruby-lang.org/https://bugs.ruby-lang.org/favicon.ico?17113305112013-07-14T17:28:36ZRuby Issue Tracking SystemRuby master - Feature #8631: Add a new method to ERB to allow assigning the local variables from a hashhttps://bugs.ruby-lang.org/issues/8631?journal_id=404952013-07-14T17:28:36Zsorah (Sorah Fukumori)her@sorah.jp
<ul><li><strong>Status</strong> changed from <i>Open</i> to <i>Assigned</i></li><li><strong>Assignee</strong> set to <i>seki (Masatoshi Seki)</i></li></ul><p>Assigning to erb maintainer;</p>
<p>IMO, I recommend you to show example mock-code that uses your proposal, to show what interface (API) do you want :)</p> Ruby master - Feature #8631: Add a new method to ERB to allow assigning the local variables from a hashhttps://bugs.ruby-lang.org/issues/8631?journal_id=405062013-07-15T21:39:17Zrosenfeld (Rodrigo Rosenfeld Rosas)rr.rosas@gmail.com
<ul></ul><p>I didn't propose an API because I don't really care about the API as long as it allows us to provide a hash instead of a binding.</p>
<p>If you want an example API that would satisfy me, I'd be happy if we used the same API (ERB#result). If the argument is a hash, use the keys as the local variables and the values as the variable values.</p> Ruby master - Feature #8631: Add a new method to ERB to allow assigning the local variables from a hashhttps://bugs.ruby-lang.org/issues/8631?journal_id=405072013-07-15T21:43:08Zrosenfeld (Rodrigo Rosenfeld Rosas)rr.rosas@gmail.com
<ul></ul><p>You can see here how often people want to use a hash to render an ERB template:</p>
<p><a href="https://github.com/search?q=erb+result+openstruct&type=Code&ref=searchresults" class="external">https://github.com/search?q=erb+result+openstruct&type=Code&ref=searchresults</a></p>
<p>And there's no quick way for performing this common procedure. The quickest one seems to be using OpenStruct for that...</p> Ruby master - Feature #8631: Add a new method to ERB to allow assigning the local variables from a hashhttps://bugs.ruby-lang.org/issues/8631?journal_id=473912014-06-26T12:49:23Zrosenfeld (Rodrigo Rosenfeld Rosas)rr.rosas@gmail.com
<ul><li><strong>File</strong> <a href="/attachments/4501">feature-8631.pdf</a> <a class="icon-only icon-download" title="Download" href="/attachments/download/4501/feature-8631.pdf">feature-8631.pdf</a> added</li></ul><p>Attached slide for proposal</p> Ruby master - Feature #8631: Add a new method to ERB to allow assigning the local variables from a hashhttps://bugs.ruby-lang.org/issues/8631?journal_id=474692014-06-30T08:07:47Znaruse (Yui NARUSE)naruse@airemix.jp
<ul></ul><p>received, thanks!</p> Ruby master - Feature #8631: Add a new method to ERB to allow assigning the local variables from a hashhttps://bugs.ruby-lang.org/issues/8631?journal_id=480442014-07-26T05:36:00Zko1 (Koichi Sasada)
<ul></ul><p>I think it is easy to implement, but not clear what is "self" on ERB evaluation context.</p>
<p>If you provide binding, self will be binding's self.</p> Ruby master - Feature #8631: Add a new method to ERB to allow assigning the local variables from a hashhttps://bugs.ruby-lang.org/issues/8631?journal_id=480452014-07-26T05:39:49Zmatz (Yukihiro Matsumoto)matz@ruby.or.jp
<ul></ul><p>I like the idea, but I have one concern.</p>
<p>The binding also has information about the receiver (which defaults to top-level self).<br>
I am not sure whether it's critical or not.</p>
<p>I hope Seki will address this.</p>
<p>Matz.</p> Ruby master - Feature #8631: Add a new method to ERB to allow assigning the local variables from a hashhttps://bugs.ruby-lang.org/issues/8631?journal_id=480502014-07-26T06:07:17Zmatsuda (Akira Matsuda)ronnie@dio.jp
<ul></ul><p>FYI here's an already existing implementation by Seki-san: <a href="https://gist.github.com/seki/6449467" class="external">https://gist.github.com/seki/6449467</a><br>
Gemified version is here: <a href="https://github.com/takkanm/erb_with_hash" class="external">https://github.com/takkanm/erb_with_hash</a></p> Ruby master - Feature #8631: Add a new method to ERB to allow assigning the local variables from a hashhttps://bugs.ruby-lang.org/issues/8631?journal_id=600302016-08-10T02:54:38Zshyouhei (Shyouhei Urabe)shyouhei@ruby-lang.org
<ul><li><strong>Related to</strong> <i><a class="issue tracker-2 status-6 priority-4 priority-default closed" href="/issues/8643">Feature #8643</a>: Add Binding.from_hash</i> added</li></ul> Ruby master - Feature #8631: Add a new method to ERB to allow assigning the local variables from a hashhttps://bugs.ruby-lang.org/issues/8631?journal_id=628902017-02-06T13:45:32Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul></ul><p>Another implementation:</p>
<pre><code class="diff syntaxhl" data-language="diff"><span class="gh">diff --git a/lib/erb.rb b/lib/erb.rb
index 9483711024..9813b4dc71 100644
</span><span class="gd">--- a/lib/erb.rb
</span><span class="gi">+++ b/lib/erb.rb
</span><span class="p">@@ -887,6 +887,11 @@</span>
# code evaluation.
#
def result(b=new_toplevel)
<span class="gi">+ if b.respond_to?(:each_pair)
+ x = new_toplevel
+ b.each_pair {|k, v| x.local_variable_set(k, v)}
+ b = x
+ end
</span> if @safe_level
proc {
$SAFE = @safe_level
</code></pre> Ruby master - Feature #8631: Add a new method to ERB to allow assigning the local variables from a hashhttps://bugs.ruby-lang.org/issues/8631?journal_id=648382017-05-16T01:22:55Zhsbt (Hiroshi SHIBATA)hsbt@ruby-lang.org
<ul><li><strong>Assignee</strong> changed from <i>seki (Masatoshi Seki)</i> to <i>k0kubun (Takashi Kokubun)</i></li><li><strong>Target version</strong> set to <i>2.5</i></li></ul> Ruby master - Feature #8631: Add a new method to ERB to allow assigning the local variables from a hashhttps://bugs.ruby-lang.org/issues/8631?journal_id=648792017-05-18T14:04:46Zk0kubun (Takashi Kokubun)takashikkbn@gmail.com
<ul></ul><p>There's a problem that a receiver is unclear and not configurable if argument is only a Hash object. To address the problem, we need to have both anything for a receiver (of course Binding is okay) and a Hash object in arguments.</p>
<p>Even in that case, most users of this feature will want to pass only a Hash object as argument. So we want to pass a Hash object with default option for its receiver, without breaking backward compatibility.</p>
<p>To solve all those problems, I propose to use keyword argument like <a href="https://github.com/ruby/ruby/pull/1618" class="external">https://github.com/ruby/ruby/pull/1618</a>.</p>
<p>Following is example use case. I think it's fairly easy to use and understand what it does.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">ERB</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="s1">'<%= my_local %>'</span><span class="p">).</span><span class="nf">result</span><span class="p">(</span><span class="ss">locals: </span><span class="p">{</span> <span class="ss">my_local: </span><span class="s1">'value'</span> <span class="p">})</span>
</code></pre> Ruby master - Feature #8631: Add a new method to ERB to allow assigning the local variables from a hashhttps://bugs.ruby-lang.org/issues/8631?journal_id=649562017-05-19T15:56:23Zk0kubun (Takashi Kokubun)takashikkbn@gmail.com
<ul></ul><p>I found that my suggestion is a little hard to implement to avoid argument modification. It got a little ugly <a href="https://github.com/ruby/ruby/pull/1618/commits/ed1c1e520eec6cb96f1eae88bef2fa4ac54a3e6c" class="external">https://github.com/ruby/ruby/pull/1618/commits/ed1c1e520eec6cb96f1eae88bef2fa4ac54a3e6c</a>.</p>
<p>Anyway, currently we have 3 possible choices.</p>
<ol>
<li>Proposed one (implementation is suggested by nobu): ERB.new(*).result({ foo: bar })</li>
<li>Seki-san's patch (erb_with_hash): ERB.new(*).result_with_hash({ foo: bar })</li>
<li>My suggestion: ERB.new(*).result(locals: { foo: bar })</li>
</ol>
<p>From user's point of view, 1 is okay but a little confusing that it can take multiple types in the same argument, 2 is good but a name is long and 3 is the best.<br>
From maintainer's point of view, 1 is okay, 2 is the best and 3 is a little hard.</p>
<p>So all of them have trade-offs. While I feel it's overkill to make it capable of having both Binding and Hash as arguments, I personally want to introduce 3 because it's easy to use and not confusing.</p>
<p>I want your opinions about this.</p> Ruby master - Feature #8631: Add a new method to ERB to allow assigning the local variables from a hashhttps://bugs.ruby-lang.org/issues/8631?journal_id=649582017-05-19T16:09:17Zk0kubun (Takashi Kokubun)takashikkbn@gmail.com
<ul></ul><p>Umm, I noticed that actually the length of "ERB.new(*).result(locals: {a: b})" is the same as "ERB.new("aaa").result_with_hash(a: b)". So the long name of 2 seems not a problem compared to 3.</p>
<p>Then, my final personal preference is Seki-san's 2 (erb_with_hash) <a href="https://github.com/ruby/ruby/pull/1623" class="external">https://github.com/ruby/ruby/pull/1623</a>. It's already used by some users of erb_with_hash.gem and I think the method is good to have in ERB.</p> Ruby master - Feature #8631: Add a new method to ERB to allow assigning the local variables from a hashhttps://bugs.ruby-lang.org/issues/8631?journal_id=649912017-05-20T17:41:25Zk0kubun (Takashi Kokubun)takashikkbn@gmail.com
<ul><li><strong>Status</strong> changed from <i>Assigned</i> to <i>Feedback</i></li></ul> Ruby master - Feature #8631: Add a new method to ERB to allow assigning the local variables from a hashhttps://bugs.ruby-lang.org/issues/8631?journal_id=650002017-05-20T20:42:40Zrosenfeld (Rodrigo Rosenfeld Rosas)rr.rosas@gmail.com
<ul></ul><p>I would already suggest a new name when I read about the problems with overriding the current method, so I would agree that 2 would be a better approach, I'm just not sure which name would be best. I like result_with_hash, but it could be result_from_locals or result_from_hash.</p>
<p>Or maybe ERB.new(str, locals: {a: b}).result?</p> Ruby master - Feature #8631: Add a new method to ERB to allow assigning the local variables from a hashhttps://bugs.ruby-lang.org/issues/8631?journal_id=650112017-05-22T03:50:41Zk0kubun (Takashi Kokubun)takashikkbn@gmail.com
<ul></ul><blockquote>
<p>Or maybe ERB.new(str, locals: {a: b}).result?</p>
</blockquote>
<p>For this case, it would have the same problem as ERB.new(str).result(locals: {a: b}) because it can have both binding and locals. In that case, adding locals to given binding is hard to maintain. Also, if we want to avoid the situation, raising error for that case does not seem a good idea (method should be separated in that case, especially for "3").</p>
<blockquote>
<p>I'm just not sure which name would be best. I like result_with_hash, but it could be result_from_locals or result_from_hash.</p>
</blockquote>
<p>Then, the remaining problem is only the name of result_with_hash counterpart. Possible choices are:</p>
<ul>
<li>result_with_hash</li>
<li>result_from_locals</li>
<li>result_from_hash</li>
</ul>
<p>What this method does is "rendering template with a context that given local variables are set and returning the result". It's not result derived from only local variables. While "locals" is longer than "hash", it describes not type of argument but its actual content.</p>
<p>So I prefer "result_with_locals" ("render_with_locals" may be better but it should be unified with "result"). If you use the method with that name, I'm okay to add that.</p> Ruby master - Feature #8631: Add a new method to ERB to allow assigning the local variables from a hashhttps://bugs.ruby-lang.org/issues/8631?journal_id=650282017-05-22T18:35:52Zrosenfeld (Rodrigo Rosenfeld Rosas)rr.rosas@gmail.com
<ul></ul><p>I'm actually fine with whatever name you prefer. result_with_locals and render_with_locals are both fine to me. Thanks a lot!</p> Ruby master - Feature #8631: Add a new method to ERB to allow assigning the local variables from a hashhttps://bugs.ruby-lang.org/issues/8631?journal_id=650912017-05-25T15:37:24Zk0kubun (Takashi Kokubun)takashikkbn@gmail.com
<ul></ul><p>I discussed about this with Seki-san.</p>
<p>For name, I rethought that "result_with_locals" sounds to use caller's local variables. Since "result_with_hash" doesn't seem to mean it and is shorter, we agreed "result_with_hash" is the best.</p>
<p>For receiver problem, since TOPLEVEL_BINDING.dup (and its receiver, main) is already used, we agreed it's consistent and safe to use TOPLEVEL_BINDING.dup.</p>
<p>As Seki-san agreed to introduce this in person, I'm going to merge <a href="https://github.com/ruby/ruby/pull/1623" class="external">https://github.com/ruby/ruby/pull/1623</a>.</p> Ruby master - Feature #8631: Add a new method to ERB to allow assigning the local variables from a hashhttps://bugs.ruby-lang.org/issues/8631?journal_id=650922017-05-25T15:38:30Zk0kubun (Takashi Kokubun)takashikkbn@gmail.com
<ul><li><strong>Status</strong> changed from <i>Feedback</i> to <i>Closed</i></li></ul><p>Applied in changeset trunk|r58891.</p>
<hr>
<p>erb.rb: Add ERB#result_with_hash</p>
<p><a href="/issues/8631">[ruby-core:55985]</a> [Feature <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: Add a new method to ERB to allow assigning the local variables from a hash (Closed)" href="https://bugs.ruby-lang.org/issues/8631">#8631</a>] [fix GH-1623]</p> Ruby master - Feature #8631: Add a new method to ERB to allow assigning the local variables from a hashhttps://bugs.ruby-lang.org/issues/8631?journal_id=650952017-05-25T18:29:46Zrosenfeld (Rodrigo Rosenfeld Rosas)rr.rosas@gmail.com
<ul></ul><p>Awesome, thanks!</p>