Class: Rhino::Ruby::Function

Inherits:
JS::BaseFunction
  • Object
show all
Includes:
JS::Wrapper, Scriptable
Defined in:
lib/rhino/ruby.rb

Direct Known Subclasses

Constructor

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Scriptable

access, access=, #get, #getIds, #has, #put

Constructor Details

#initialize(callable, scope) ⇒ Function

Returns a new instance of Function.



141
142
143
144
145
# File 'lib/rhino/ruby.rb', line 141

def initialize(callable, scope)
  super()
  @callable = callable
  JS::ScriptRuntime.setFunctionProtoAndParent(self, scope) if scope
end

Class Method Details

.wrap(callable, scope = nil) ⇒ Object

wrap a callable (Method/Proc)



135
136
137
138
139
# File 'lib/rhino/ruby.rb', line 135

def self.wrap(callable, scope = nil)
  # NOTE: include JS::Wrapper & Ruby.cache(callable.to_s) guarantees === 
  # in Rhino although if a bind Method gets passed it might get confusing
  Ruby.cache(callable.to_s) { new(callable, scope) }
end

Instance Method Details

#call(*args) ⇒ Object Also known as: __call__

override Object BaseFunction#call(Context context, Scriptable scope,

Scriptable thisObj, Object[] args)


179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
# File 'lib/rhino/ruby.rb', line 179

def call(*args)
  unless args.first.is_a?(JS::Context)
    return super # assume a Ruby #call
  end
  _, scope, this, args = *args # Java Function#call dispatch
  args = args.to_a # java.lang.Object[] -> Array
  # JS function style :
  if ( arity = @callable.arity ) != -1 # (a1, *a).arity == -2
    if arity > -1 && args.size > arity # omit 'redundant' arguments
      args = args.slice(0, arity)
    elsif arity > args.size || # fill 'missing' arguments
        ( arity < -1 && (arity = arity.abs - 1) > args.size )
      (arity - args.size).times { args.push(nil) }
    end
  end
  rb_args = Rhino.args_to_ruby(args)
  begin
    callable = 
      if @callable.is_a?(UnboundMethod)
        @callable.bind(Rhino.to_ruby(this)) # might end up as TypeError
      else
        @callable
      end
    result = callable.call(*rb_args)
  rescue StandardError, ScriptError => e
    raise Ruby.wrap_error(e) # thus `try { } catch (e)` works in JS
  end
  Rhino.to_javascript(result, scope)
end

#equivalentValues(other) ⇒ Object Also known as: ==

protected Object ScriptableObject#equivalentValues(Object value)



168
169
170
171
172
173
174
# File 'lib/rhino/ruby.rb', line 168

def equivalentValues(other) # JS == operator
  return false unless other.is_a?(Function)
  return true if unwrap == other.unwrap
  # Method.== does check if their bind to the same object
  # JS == means they might be bind to different objects :
  unwrap.to_s == other.unwrap.to_s # "#<Method: Foo#bar>"
end

#getArityObject

#deprecated int BaseFunction#getArity()



158
159
160
# File 'lib/rhino/ruby.rb', line 158

def getArity
  getLength
end

#getFunctionNameObject

override String BaseFunction#getFunctionName()



163
164
165
# File 'lib/rhino/ruby.rb', line 163

def getFunctionName
  @callable.is_a?(Proc) ? "" : @callable.name
end

#getLengthObject

override int BaseFunction#getLength()



152
153
154
155
# File 'lib/rhino/ruby.rb', line 152

def getLength
  arity = @callable.arity
  arity < 0 ? ( arity + 1 ).abs : arity
end

#unwrapObject



147
148
149
# File 'lib/rhino/ruby.rb', line 147

def unwrap
  @callable
end