A SassScript parse node representing a function call.
A function call either calls one of the functions in {Script::Functions}, or if no function with the given name exists it returns a string representation of the function call.
The arguments to the function.
@return [Array<Script::Node>]
The keyword arguments to the function.
@return [{String => Script::Node}]
The name of the function.
@return [String]
The splat argument for this function, if one exists.
@return [Script::Node?]
@param name [String] See {#name} @param args [Array<Script::Node>] See {#args} @param splat [Script::Node] See {#splat} @param keywords [{String => Script::Node}] See {#keywords}
# File lib/sass/script/funcall.rb, line 35 def initialize(name, args, keywords, splat) @name = name @args = args @keywords = keywords @splat = splat super() end
Returns the arguments to the function.
@return [Array<Node>] @see Sass::Script::Node#children
# File lib/sass/script/funcall.rb, line 71 def children res = @args + @keywords.values res << @splat if @splat res end
@see Sass::Script::Node#deep_copy
# File lib/sass/script/funcall.rb, line 78 def deep_copy node = dup node.instance_variable_set('@args', args.map {|a| a.deep_copy}) node.instance_variable_set('@keywords', Hash[keywords.map {|k, v| [k, v.deep_copy]}]) node end
@return [String] A string representation of the function call
# File lib/sass/script/funcall.rb, line 44 def inspect args = @args.map {|a| a.inspect}.join(', ') keywords = Sass::Util.hash_to_a(@keywords). map {|k, v| "$#{k}: #{v.inspect}"}.join(', ') if self.splat splat = (args.empty? && keywords.empty?) ? "" : ", " splat = "#{splat}#{self.splat.inspect}..." end "#{name}(#{args}#{', ' unless args.empty? || keywords.empty?}#{keywords}#{splat})" end
@see Sass::Script::Node#to_sass
# File lib/sass/script/funcall.rb, line 56 def to_sass(opts = {}) args = @args.map {|a| a.to_sass(opts)}.join(', ') keywords = Sass::Util.hash_to_a(@keywords). map {|k, v| "$#{dasherize(k, opts)}: #{v.to_sass(opts)}"}.join(', ') if self.splat splat = (args.empty? && keywords.empty?) ? "" : ", " splat = "#{splat}#{self.splat.inspect}..." end "#{dasherize(name, opts)}(#{args}#{', ' unless args.empty? || keywords.empty?}#{keywords}#{splat})" end
Evaluates the function call.
@param environment [Sass::Environment] The environment in which to evaluate the SassScript @return [Literal] The SassScript object that is the value of the function call @raise [Sass::SyntaxError] if the function call raises an ArgumentError
# File lib/sass/script/funcall.rb, line 92 def _perform(environment) args = @args.map {|a| a.perform(environment)} splat = @splat.perform(environment) if @splat if fn = environment.function(@name) keywords = Sass::Util.map_hash(@keywords) {|k, v| [k, v.perform(environment)]} return perform_sass_fn(fn, args, keywords, splat) end ruby_name = @name.tr('-', '_') args = construct_ruby_args(ruby_name, args, splat, environment) unless Functions.callable?(ruby_name) opts(to_literal(args)) else opts(Functions::EvaluationContext.new(environment.options).send(ruby_name, *args)) end rescue ArgumentError => e # If this is a legitimate Ruby-raised argument error, re-raise it. # Otherwise, it's an error in the user's stylesheet, so wrap it. if e.message =~ %r^wrong number of arguments \(\d+ for \d+\)/ && e.backtrace[0] !~ %r:in `(block in )?#{ruby_name}'$/ && # JRuby (as of 1.6.7.2) doesn't put the actual method for # which the argument error was thrown in the backtrace, so # we detect whether our send threw an argument error. (RUBY_PLATFORM !~ %rjava/ || e.backtrace[0] !~ %r:in `send'$/ || e.backtrace[1] !~ %r:in `_perform'$/) raise e end raise Sass::SyntaxError.new("#{e.message} for `#{name}'") end
This method is factored out from `_perform` so that compass can override it with a cross-browser implementation for functions that require vendor prefixes in the generated css.
# File lib/sass/script/funcall.rb, line 126 def to_literal(args) Script::String.new("#{name}(#{args.join(', ')})") end