{
    "componentChunkName": "component---src-templates-blog-post-tsx",
    "path": "/blog/2010-10-25-accessing-javascript-objects-from-ruby/",
    "result": {"data":{"blogPost":{"title":"Accessing Javascript Objects from Ruby","slug":"/blog/2010-10-25-accessing-javascript-objects-from-ruby/","authorNodes":[{"name":"Charles Lowell","slug":"/people/charles-lowell/"}],"markdown":{"html":"<p>Awhile back, I wrote a post on how to <a href=\"/2010/06/30/accessing-ruby-objects-from-V8/\">access Ruby objects from inside your JavaScript enviroment</a> when using <a href=\"http://github.com/cowboyd/therubyracer\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">The Ruby Racer</a>. It showed just some of the many ways that you can access Ruby state and call Ruby code from within JavaScript. However, the story doesn't end there. The Ruby Racer is, after all, a two way bridge, and I thought it would be useful to document some of the ways in which you can access your JavaScript environment from within Ruby.</p>\n<p>Let's start with the <code class=\"language-text\">Context#eval</code> method, which is used to execute JavaScript code from Ruby. Its the most intuitive way,\nand what gets used most often for examples.</p>\n<p>Given a string, it compiles it as JavaScript source and then executes it inside the context. Nothing\ncrazy there:</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">V8::Context.new do |cxt|\n  cxt.eval('1 + 1') #=> 2\n  cxt.eval('foo = {bar: \"bar\", baz: \"baz\"}')\n  cxt.eval('foo.bar') #=> \"bar\"\n  cxt.eval('foo.baz') #=> \"baz\"\n  cxt.eval('new Object()') #=> [object Object]\nend</code></pre></div>\n<p>Among other things, the context captures what functions and objects are defined in the global scope\nwhenever anything gets <code class=\"language-text\">eval()</code>'d. So, for example, the <code class=\"language-text\">Object</code> constructor used in the last line is stored\nin the context.</p>\n<p>As a tool for embedding however, <code class=\"language-text\">eval()</code> is the most blunt and (often) inefficient method available.\nFor this reason <a href=\"http://github.com/cowboyd/therubyracer\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">The Ruby Racer</a>, sports an extensive Ruby API for\ninteracting with JavaScript objects which includes accessing properties, calling functions and methods, as well\nas creating new instances. In fact, I rarely use <code class=\"language-text\">eval()</code> <em>at all</em> to manipulate a JavaScript context\nexcept for loading source files into the interpreter.</p>\n<p>The Ruby API consists of <code class=\"language-text\">V8::Object</code> and all of its subclasses:</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">V8::Context.new do |cxt|\n  cxt.eval('new Object()').class #=> V8::Object\n  cxt.eval('(function() {})').class #=> V8::Function\n  cxt.eval('new Array()).class #=> V8::Array\nend</code></pre></div>\n<h2 id=\"objects\" style=\"position:relative;\"><a href=\"#objects\" aria-label=\"objects permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Objects</h2>\n<p>The most fundamental operations in dealing with JavaScript objects are the getting and setting of values.\nCoincidentally, this is also a fundamental concept in Ruby, so it comes as no great surprise that we can re-use\nthose constructs in Ruby that deal with property access to mirror those same operations on their JavaScript\ncounterparts: the <code class=\"language-text\">[]()</code>/<code class=\"language-text\">[]=()</code> and <code class=\"language-text\">foo()</code>/<code class=\"language-text\">foo=()</code> methods:</p>\n<p>given the following context:</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">cxt = V8::Context.new\norder = cxt.eval('order = {eggs: \"over-easy\"}')</code></pre></div>\n<p>we can read the <code class=\"language-text\">eggs</code> property of our order in several differnt ways.\nVia hash access (note that both string and symbol are acceptable as key values):</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">order['eggs'] #=> \"over-easy\"\norder[:eggs] #=> \"over-easy\"</code></pre></div>\n<p>Values can be set with the hash-style access as well, and changes made from Ruby\nwill be reflected accordingly on the JavaScript side</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">order['eggs'] = \"sunny side up\"\ncxt.eval('order.eggs') #=> \"sunny side up\"</code></pre></div>\n<p>For property names that are also valid Ruby method names, you can access them just\nlike you would with Ruby properties declared with <code class=\"language-text\">attr_reader</code> or <code class=\"language-text\">attr_accessor</code>. Again,\nchanges made to the object in this way will be reflected in JavaScript:</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">  order.eggs #=> \"sunny side up\"\n  order.eggs = \"scrambled\"\n  cxt.eval('order.eggs') #=> \"scrambled\"\nend</code></pre></div>\n<p>In the cases where the property name is not a valid Ruby method name, hash-style access is mandatory:</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">order['Extra $%#@! Mayonaise!'] = true</code></pre></div>\n<p><code class=\"language-text\">V8::Object</code> also includes <code class=\"language-text\">Enumerable</code> and allows you to access all properties of a given object.</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">order.each do |key, value|\n  puts \"#{key} -> #{value}\"\nend\n\n#outputs:\neggs -> scrambled\nExtra $%#@! Mayonaise! -> true</code></pre></div>\n<p>As a convenience, <code class=\"language-text\">V8::Context</code> delegates the hash access functions to the JavaScript object which serves\nas its global scope.</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">order == cxt['order'] #=> true\norder == cxt.scope['order'] #=> true</code></pre></div>\n<h2 id=\"arrays\" style=\"position:relative;\"><a href=\"#arrays\" aria-label=\"arrays permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Arrays</h2>\n<p>Not much to see here, but before you move along: A <code class=\"language-text\">V8::Array</code> is like every other <code class=\"language-text\">V8::Object</code> except it has a <code class=\"language-text\">length</code> property, and\nit enumerates over the items stored at indices instead of the key, value pairs of its properties.</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">array = cxt.eval('[\"green\", \"red\", \"golden\"]')\narray.length #=> 3\narray.map {|color| \"#{color} slumbers\"} #=> ['green slumbers', 'red slumbers', 'golden slumbers']</code></pre></div>\n<a name=\"functions\">\n</a>\n<h2 id=\"functions\" style=\"position:relative;\"><a href=\"#functions\" aria-label=\"functions permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Functions</h2>\n<p>Consider the classic \"Circle\" example from every object oriented playbook you'll ever read. In JavaScript,\nthe way to implement the circle \"class\" is with a constructor function.</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">circle = cxt.eval&lt;&lt;-JS\n  function Circle(radius) {\n    this.radius = radius\n    this.area = function() {\n      return this.radius * this.radius * Math.PI\n    }\n    this.circumference = function() {\n      return 2 * Math.PI * this.radius\n    }\n  }\n  new Circle(5)\nJS</code></pre></div>\n<p>Now that we have the <code class=\"language-text\">Circle</code> constructor defined, and we have a reference to an instance of it in Ruby,\nwe can call its methods just as though it were a normal Ruby object. Of course, only we know\nthat under the covers the implementation is actually in JavaScript:</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">circle.class            #=> V8::Object\ncircle.radius           #=> 5\ncircle.area()           #=> 25Π\ncircle.circumference()  #=> 10Π</code></pre></div>\n<p>In JavaScript, methods are just object properties that happen to be functions. Therefore, you can get\na reference to the actual function value just as you could from JavaScript simply by accessing the property\nby name. The resulting value is an instance of <code class=\"language-text\">V8::Function</code>.</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">area =                circle['area']\ncircumference =       circle['circumference']\narea.class            #=> V8::Function\ncircumference.class   #=> V8::Function</code></pre></div>\n<p>Once you have a reference to a <code class=\"language-text\">V8::Function</code>, there are two ways to call the underlying JavaScript code\n(Actually there are three, but the third will be covered in the next section). These are the <code class=\"language-text\">call()</code> and\n<code class=\"language-text\">methodcall()</code> methods. To understand the difference between these two methods, it helps to understand how\nJavaScript functions themselves are invoked. In the event, there is the option to pass an object\nwhich will serve as the implicit invocant or <code class=\"language-text\">this</code> value. If no <code class=\"language-text\">this</code> is provided, the function will\nuse the global scope in its place. Take for example the following JavaScript</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">var circle = new Circle(5)\nvar area = circle.area  //=> [object Function]\n//no invocant, corresponds to ruby call()\narea()  //=> NaN, there is no global 'radius'.\n//call with invocant, corresponds ruby methodcall()\narea.apply(circle)  //=> 25Π</code></pre></div>\n<p>The same code in Ruby:</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">area = circle['area']\narea.class              #=> V8::Function\narea.call()             #=> NaN\narea.methodcall(circle) #=> 25Π</code></pre></div>\n<p>Because of this mechanism, JavaScript method invocation is much more flexible than Ruby in the sense that\nvirtually <em>any</em> object can be used as the invocant of <em>any</em> function provided it has the requisite properties\nto satisfy the function's requirements:</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">area.methodcall(:radius => 5) #=> 25Π\nother_circle = OpenStruct.new\nother_circle.radius = 10\narea.methodcall(other_circle) #=> 100Π</code></pre></div>\n<p>A very powerful construct indeed.</p>\n<h2 id=\"constructors\" style=\"position:relative;\"><a href=\"#constructors\" aria-label=\"constructors permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Constructors</h2>\n<p>But wait, there's more! Any JavaScript function can be either invoked normally, or, combined with the <code class=\"language-text\">new</code> keyword,\nas a <em>constructor</em>. It's what we used in the original eval() block to create the instance of <code class=\"language-text\">Circle</code> whose methods we were messing\nabout with.</p>\n<p>That was not quite necessary since we can invoke functions as constructors from Ruby too. This is done with the <code class=\"language-text\">new</code>\nmethod of <code class=\"language-text\">V8::Function</code>.</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">Circle = cxt['Circle']\ncircle2 = Circle.new(3)\ncircle2.radius        #=> 3\ncircle2.area          #=> 9Π\ncircle2.circumference #=> 6Π</code></pre></div>\n<p>Interestingly, when used as a constructor, a JavaScript function is almost completely indistinguishable from a Ruby class.\nThis apparent duality between classes and functions is behind the decision to <a href=\"/2010/06/30/accessing-ruby-objects-from-V8#classes\">represent Ruby classes reflected into JavaScript as functions</a></p>\n<p>The driving goal in all of these cases is the ability to author intuitive, tightly bound JavaScript, which necessarily doesn't\ninvolve evaluating strings to get what you want done. In closing, if there is something missing from this API you think would\nbe useful, I would love to <a href=\"http://github.com/cowboyd/therubyracer/issues\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">hear about it</a></p>","frontmatter":{"date":"October 25, 2010","description":null,"tags":["javascript","ruby","therubyracer"],"img":null}}}},"pageContext":{"id":"581a91cf-5326-546f-b793-dbd69b6f6d52"}},
    "staticQueryHashes": ["1241260443"]}