lib/json_builder/compiler.rb in json_builder-3.0.6 vs lib/json_builder/compiler.rb in json_builder-3.0.7

- old
+ new

@@ -1,87 +1,176 @@ require 'json_builder/member' module JSONBuilder class Compiler class << self + # Public: The helper that builds the JSON structure by calling the + # specific methods needed to build the JSON. + # + # args - Any number of arguments needed for the JSONBuilder::Compiler. + # block - Yielding a block to generate the JSON. + # + # Returns a String. def generate(*args, &block) options = args.extract_options! compiler = self.new(options) compiler.compile(*args, &block) compiler.finalize end end - + attr_accessor :members attr_accessor :array attr_accessor :scope attr_accessor :callback attr_accessor :pretty_print - + + # Needed to allow for the id key to be used undef_method :id if methods.include? 'id' - + + # Public: Creates a new Compiler instance used to hold any and + # all JSONBuilder::Member objects. + # + # options - Hash of options used to modify JSON output. + # + # Examples + # + # json = JSONBuilder::Compiler.new(:callback => false) + # json.compile do + # name 'Garrett' + # end + # json.finalize + # # => {"name": "Garrett"} + # + # Returns instance of JSONBuilder::Compiler. def initialize(options={}) @_members = [] @_scope = options[:scope] @_callback = options[:callback] || true @_pretty_print = options[:pretty] || false - + # Only copy instance variables if there is a scope and presence of Rails copy_instance_variables_from(@_scope) if @_scope end - + + # Public: Takes a block to generate the JSON structure by calling method_missing + # on all members passed to it through the block. + # + # args - An array of values passed to JSONBuilder::Value. + # block - Yielding a block to generate the JSON. + # + # Returns nothing. def compile(*args, &block) instance_exec(*args, &block) end - + + # Public: Takes a set number of items to generate a plain JSON array response. + # + # Returns instance of JSONBuilder::Elements. def array(items, &block) @_array = Elements.new(@_scope, items, &block) end - - # Need to return a Key instance to allow for arrays to be handled appropriately + + # Public: Called anytime the compiler is passed JSON keys, + # first checks to see if the parent object contains the method like + # a Rails helper. + # + # key_name - The key for the JSON member. + # args - An array of values passed to JSONBuilder::Value. + # block - Yielding any block passed to the element. + # + # Returns nothing. def method_missing(key_name, *args, &block) if @_scope.respond_to?(key_name) && !ignore_scope_methods.include?(key_name) @_scope.send(key_name, *args, &block) else key(key_name, *args, &block) end end - + + # Public: Generates the start of the JSON member. Useful if the key you are + # generating is dynamic. + # + # key - Used to generate the JSON member's key. Can be a String or Symbol. + # args - An array of values passed to JSONBuilder::Value. + # block - Yielding any block passed to the element. + # + # Examples + # + # key :hello, 'Hi' + # # => "hello": "Hi" + # + # key "item-#{rand(0, 500)}", "I'm random!" + # # => "item-250": "I'm random!" + # + # Returns instance of JSONBuilder::Member. def key(key_name, *args, &block) member = Member.new(key_name, @_scope, *args, &block) @_members << member member end - + + # Public: Combines the output of the compiled members and the change + # there is a JSONP callback. This is what is returned in the response. + # + # Returns a String. def finalize include_callback to_s end - - # Once all nodes are compiled, build the string + + # Public: Gathers the JSON structure and calls it's compiler within each + # instance. + # + # Returns a String. def to_s @_array ? @_array.to_s : "{#{@_members.collect(&:to_s).join(', ')}}" end - + private - + + # Private: Determines whether or not to include a JSONP callback in + # the response. + # + # json - The String representation of the JSON structure. + # + # Returns a String. def include_callback(json) @_callback && request_params[:callback] ? "#{request_params[:callback]}(#{pretty_print(json)})" : pretty_print(json) end - + + # Private: Determines whether or not to pass the string through the a + # JSON prettifier to help with debugging. + # + # json - The String representation of the JSON structure. + # + # Returns a String. def pretty_print(json) @_pretty_print ? JSON.pretty_generate(JSON[json]) : json end - + + # Private: Contains the params from the request. + # + # Returns a Hash. def request_params @_scope.respond_to?(:params) ? @_scope.params : {} end - + + # Private: Takes all instance variables from the scope passed to it + # and makes them available to the block that gets compiled. + # + # object - The scope which contains the instance variables. + # exclude - Any instance variables that should not be set. + # + # Returns nothing. def copy_instance_variables_from(object, exclude = []) #:nodoc: vars = object.instance_variables.map(&:to_s) - exclude.map(&:to_s) vars.each { |name| instance_variable_set(name.to_sym, object.instance_variable_get(name)) } end - - # There are some special methods that need to be ignored that may be matched within +@_scope+. + + # Private: Array of instance variable names that should not be set for + # the scope. + # + # Returns an Array of Symbols. def ignore_scope_methods [:id] end end end