You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@whimsical.apache.org by Craig Russell <ap...@gmail.com> on 2020/06/27 19:49:23 UTC

Problems understanding hashes in roster-emeritus ruby->js

I'm having some trouble with the memstat.rb.js code, specifically with the committer.forms implementation. [1]

I'm guessing that the implementation of hashes in the rb->js compiler is inconsistent with my usage of it.

Thanks,
Craig

[1]
This code works:

            for form in committer.forms
              link = committer.forms[form]
              console.log("#{form}: #{link}")

[Log] icla: https://svn.apache.org/repos/private/documents/iclas/craig-russell.pdf (app.js, line 4057)
[Log] member: https://svn.apache.org/repos/private/documents/member_apps/craig-l-russell.pdf (app.js, line 4057)
[Log] emeritus_rescinded: https://svn.apache.org/repos/private/documents/emeritus-requests-rescinded/craig-l-russell.txt (app.js, line 4057)

This code compiles but fails at execution time:

            committer.forms.each do |form, link|
              console.log("#{form}: #{link}")
            end

TypeError: committer.forms.forEach is not a function. (In 'committer.forms.forEach(function(form, link) {
                console.log(form + ": " + link)
              })', 'committer.forms.forEach' is undefined)

Craig L Russell
clr@apache.org


Re: Problems understanding hashes in roster-emeritus ruby->js

Posted by Craig Russell <ap...@gmail.com>.
Hi Sam,

Thanks for explaining. The each_pair method works great.

Your commentary on javascript and ecma standard is fascinating. Sadly, I do not have the energy to keep up with it all.

Craig


> On Jun 27, 2020, at 3:13 PM, Sam Ruby <ru...@intertwingly.net> wrote:
> 
> On Sat, Jun 27, 2020 at 3:49 PM Craig Russell <ap...@gmail.com> wrote:
>> 
>> I'm having some trouble with the memstat.rb.js code, specifically with the committer.forms implementation. [1]
>> 
>> I'm guessing that the implementation of hashes in the rb->js compiler is inconsistent with my usage of it.
> 
> There are two separate problems here.
> 
> The first problem is that Ruby2JS is not smart enough to know that
> committer_forms is a hash, so it maps each to forEach, which is the
> common use case.  However, each_pair is a method that
> is unique to hashes, so you can do what you want merely by
> substituting each_pair for each.
> 
> https://apidock.com/ruby/Hash/each_pair
> 
> Next, if you look at the code that is generated, it basically compiles
> it to the code that works[1], as that is the best that you can do with
> JavaScript that runs across all browsers (including Internet Explorer
> and Opera mini).
> 
> In 2017, ECMAScript introduced Object.entries which lets you get
> access to key value pairs:
> 
> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries
> https://caniuse.com/#feat=object-entries
> 
> .If you were to enable es2017 (or later) support, ruby2js will make us
> of Object.entries.  You can enable es2017 support by adding the
> following line to the application:
> 
> require 'ruby2js/es2017'
> 
>> Thanks,
>> Craig
> 
> - Sam Ruby
> 
>> [1]
>> This code works:
>> 
>>            for form in committer.forms
>>              link = committer.forms[form]
>>              console.log("#{form}: #{link}")
>> 
>> [Log] icla: https://svn.apache.org/repos/private/documents/iclas/craig-russell.pdf (app.js, line 4057)
>> [Log] member: https://svn.apache.org/repos/private/documents/member_apps/craig-l-russell.pdf (app.js, line 4057)
>> [Log] emeritus_rescinded: https://svn.apache.org/repos/private/documents/emeritus-requests-rescinded/craig-l-russell.txt (app.js, line 4057)
>> 
>> This code compiles but fails at execution time:
>> 
>>            committer.forms.each do |form, link|
>>              console.log("#{form}: #{link}")
>>            end
>> 
>> TypeError: committer.forms.forEach is not a function. (In 'committer.forms.forEach(function(form, link) {
>>                console.log(form + ": " + link)
>>              })', 'committer.forms.forEach' is undefined)
>> 
>> Craig L Russell
>> clr@apache.org
>> 

Craig L Russell
clr@apache.org


Re: Problems understanding hashes in roster-emeritus ruby->js

Posted by Sam Ruby <ru...@intertwingly.net>.
On Sat, Jun 27, 2020 at 3:49 PM Craig Russell <ap...@gmail.com> wrote:
>
> I'm having some trouble with the memstat.rb.js code, specifically with the committer.forms implementation. [1]
>
> I'm guessing that the implementation of hashes in the rb->js compiler is inconsistent with my usage of it.

There are two separate problems here.

The first problem is that Ruby2JS is not smart enough to know that
committer_forms is a hash, so it maps each to forEach, which is the
common use case.  However, each_pair is a method that
is unique to hashes, so you can do what you want merely by
substituting each_pair for each.

https://apidock.com/ruby/Hash/each_pair

Next, if you look at the code that is generated, it basically compiles
it to the code that works[1], as that is the best that you can do with
JavaScript that runs across all browsers (including Internet Explorer
and Opera mini).

In 2017, ECMAScript introduced Object.entries which lets you get
access to key value pairs:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries
https://caniuse.com/#feat=object-entries

.If you were to enable es2017 (or later) support, ruby2js will make us
of Object.entries.  You can enable es2017 support by adding the
following line to the application:

require 'ruby2js/es2017'

> Thanks,
> Craig

- Sam Ruby

> [1]
> This code works:
>
>             for form in committer.forms
>               link = committer.forms[form]
>               console.log("#{form}: #{link}")
>
> [Log] icla: https://svn.apache.org/repos/private/documents/iclas/craig-russell.pdf (app.js, line 4057)
> [Log] member: https://svn.apache.org/repos/private/documents/member_apps/craig-l-russell.pdf (app.js, line 4057)
> [Log] emeritus_rescinded: https://svn.apache.org/repos/private/documents/emeritus-requests-rescinded/craig-l-russell.txt (app.js, line 4057)
>
> This code compiles but fails at execution time:
>
>             committer.forms.each do |form, link|
>               console.log("#{form}: #{link}")
>             end
>
> TypeError: committer.forms.forEach is not a function. (In 'committer.forms.forEach(function(form, link) {
>                 console.log(form + ": " + link)
>               })', 'committer.forms.forEach' is undefined)
>
> Craig L Russell
> clr@apache.org
>