joenoon / libphonenumber-execjs

ExecJS wrapper for Google's libphonenumber library
MIT License
8 stars 9 forks source link

ExecJS::ProgramError: TypeError: Object #<Object> has no method 'parseHelper_' #2

Open mattconnolly opened 11 years ago

mattconnolly commented 11 years ago

I'm getting the following error when using libphonenumber-execjs (0.0.2) from ruby 1.9.3 (from irb):

1.9.3p286 :006 > libphonenumber.parse("9255550100", "US")     
ExecJS::ProgramError: TypeError: Object #<Object> has no method 'parseHelper_'
        from /usr/local/rvm/gems/ruby-1.9.3-p286/gems/execjs-1.4.0/lib/execjs/external_runtime.rb:68:in `extract_result'
        from /usr/local/rvm/gems/ruby-1.9.3-p286/gems/execjs-1.4.0/lib/execjs/external_runtime.rb:28:in `block in exec'
        from /usr/local/rvm/gems/ruby-1.9.3-p286/gems/execjs-1.4.0/lib/execjs/external_runtime.rb:41:in `compile_to_tempfile'
        from /usr/local/rvm/gems/ruby-1.9.3-p286/gems/execjs-1.4.0/lib/execjs/external_runtime.rb:27:in `exec'
        from /usr/local/rvm/gems/ruby-1.9.3-p286/gems/execjs-1.4.0/lib/execjs/external_runtime.rb:19:in `eval'
        from /usr/local/rvm/gems/ruby-1.9.3-p286/gems/execjs-1.4.0/lib/execjs/external_runtime.rb:33:in `call'
        from /usr/local/rvm/gems/ruby-1.9.3-p286/gems/libphonenumber-execjs-0.0.2/lib/libphonenumber-execjs/libphonenumber.rb:18:in `parse'
        from (irb):6
        from /usr/local/rvm/rubies/ruby-1.9.3-p286/bin/irb:16:in `<main>'

Is ruby 1.9.3 supported? Or is this a Javascript problem?

joenoon commented 11 years ago

I'm not sure why this started happening, or if it was always a problem. It looks like execjs's #call uses apply and changes the context the function expects to have, resulting in the error. Here are some workarounds:

You can add a wrapping function around the parse fn, to protect the context of 'this' in the parse fn:

$libphonenumber.context.call "(function (a,b) { return i18n.phonenumbers.PhoneNumberUtil.getInstance().parse(a,b); })", "+19255550100", "US"

Or you can use eval directly:

$libphonenumber.context.eval "(function () { inst = i18n.phonenumbers.PhoneNumberUtil.getInstance(); return inst.parse('9255550100', 'US'); })()"

$libphonenumber.context.eval "(function () { inst = i18n.phonenumbers.PhoneNumberUtil.getInstance(); phone_obj = inst.parse('9255550100', 'US'); return inst.isValidNumber(phone_obj); })()"

Unfortunately I don't have time right now to dive too deep into this and make sure these are the correct solutions, but I'll try and patch this up in the library soon.