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