Class: RVM::Functions::Function

Inherits:
Object
  • Object
show all
Extended by:
Plugin
Defined in:
lib/rvm/functions.rb

Overview

Basic Parent for every function defined, it registers it to the PluginHost and sets up some basic functionality. Just parent a class to this and define execute as a class function and it can be handled.

Class Method Summary collapse

Methods included from Plugin

helper, included, plugin_host, plugin_id, register_for

Class Method Details

.call(params, env, pos = []) ⇒ Object

Call is used to call the function it handles translating the passed parameters to the correct types or throw a exception if RVM::strict is set. This is what you want if you call a function to ensure all parameters are passed correctly.



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/rvm/functions.rb', line 52

def call params, env, pos = []
  i = 0
  pos ||= []
  # We want to make sure that if we don't have signatures from the
  # function we have a default signature of any to prevent automatic
  # type castng in that case
  sig = :any 
  params.map! do |p| 
    # We try to get the next signature if we don't have any further we
    # take the last one used so [:number, :number, :number] behaves the
    # same as just [:number] as it will be repeated
    sig = signature[i] || sig
    # Now we check if the expected type is not ':any' nor the current 
    # argument has the right type.
    if sig != :any and p.class != RVM::Classes[sig]
      # Okay if we have RVM::strict set we don't allow auto type
      # casting so we throw a Exception
      raise "TYPE MISMATCH! expected #{sig} got #{p.class}(#{pos.join(':')}) at " if RVM::strict
      # Otherwise we try to typecast the parameter.
      p = RVM::Classes[sig].new(p)
    end
    # Go to the next parameter in the list
    i+=1
    # and make sure the former one is replaced (value of the block)
    p 
  end if not signature.empty?
  # Now we execute the function code and cache the esult
  begin
    r = execute(params, env)
  rescue Exception => e
    raise "#{e} at #{pos.join(':')}"
  end
  # print a debug message if needed
  RVM::debug "#{self.inspect}: #{signature.inspect} = '#{r}'" if $DEBUG
  r
end

.data_typeObject

By default every function should have a universal return value, this make sure it is not refused if it isn’t defined correctly.



22
23
24
# File 'lib/rvm/functions.rb', line 22

def data_type
  :any
end

.execargsObject

This is for letting he itnerpreter know that it shall interprete the arguments and not let the function do it itself (this is needed for logical functions)



42
43
44
# File 'lib/rvm/functions.rb', line 42

def execargs
  true
end

.execute(params, env) ⇒ Object

This executes the function code and returns the result.

It must be implemented for every function used otherwise it will end up without doing anything.



94
95
96
# File 'lib/rvm/functions.rb', line 94

def execute params, env
  RVM::Classes[:error].new(1,"Function code for #{self} not implemented.")
end

.method_missing(m, *args, &block) ⇒ Object

We want to allow functions to call other functions without going through explic calls. Again it isn’t exactly encuraged but possible if needed to.



29
30
31
32
33
34
35
36
37
38
# File 'lib/rvm/functions.rb', line 29

def method_missing(m, *args, &block)
  # First we check if a function with the name given is defined vor rVM
  if (RVM::Functions::has? m)
    # if so we call it with the given arguments
    RVM::Functions[m].execute args, @env 
  else
    # If not we let ruby do it's magic.
    super(m, *args, &block)
  end
end