Black Dynamite
Black Dynamite

Reputation: 4147

What does this Ruby line say?

I am working with a custom renderer, and I used some copy paste from another site. I can't seem to figure out what this piece is doing right here.

"#{options[:callback]}(#{data})"

Here is the piece of code in full context.

  ActionController.add_renderer :as3 do |data, options|
    data = ActiveSupport::JSON.encode(data) unless data.respond_to?(:to_str)
    data = "#{options[:callback]}(#{data})" unless options[:callback].blank?
    self.content_type ||= Mime::JSON
    self.response_body = data
  end

Upvotes: 0

Views: 82

Answers (4)

Michelle Tilley
Michelle Tilley

Reputation: 159115

This is converting a JSON response to JSONP; imagine data is:

'{"some": "thing", "goes": "here"}'

JSONP states that the data should be wrapped in a JavaScript function call. So of options[:callback] is the string test (the name of the function to call), the resulting JSONP would be:

'test({"some": "thing", "goes": "here"})'

Upvotes: 1

Reactormonk
Reactormonk

Reputation: 21730

You can rewrite

"#{options[:callback]}(#{data})"

as

options[:callback].to_s + "(" + data.to_s + ")"

Upvotes: 0

Charlie Martin
Charlie Martin

Reputation: 112386

It's a template that replaces the first field with the value of options poiinted to by the interned string :callback, and the second field, inside the parens with the contents of data.

I'd bet a buck that the resulting string is going to be eval'd somewhere else, where it will become a call to a procedure. That would work something like this:

options[:callback] = "foo"
data="arg,arg,arg"

(Notice that data is being encoded into JSON, so the string passed as data is a json string.

The string then turns into "foo(arg.arg.arg)", and when it's eval'd it becomes a call to routine foo with those arguments.

http://www.ruby-doc.org/core-1.9.3/Kernel.html#method-i-eval

Update:

Actually, I take it back about the Ruby eval -- although that would work, it's more likely turning into a Javascript function call. This would then let you pass the name of a javascript function as a string and the code would return the appropriate callback function for execution by javascript later.

Upvotes: 0

user229044
user229044

Reputation: 239382

It's simple string interpolation. It will produce a string like this, where callback is the value of options[:callback], and value is whatever is in the variable data.

"callback(value)"

In Ruby, double-quoted strings support interpolation via #{} syntax. That is, if you have a variable x containing the value 3, the string "The value of x is #{x}" will be evaluated to "The value of x is 3". Inside a #{} you can have any arbitrarily complex Ruby expression, including array/hash indexing. So, the first part of the string, "#{options[:callback]}" is simply substituting the value of options[:callback] into the string.

The next part, the () is simply raw string data, not executable code. Inside the (), you have a second #{} substitution of data. It might be clearer if you replace the two variable substituions with x and y:

 x = 3
 y = 4
 "#{ x }(#{ y })"

The above will evaluate to the string "3(4)"

Upvotes: 4

Related Questions