class Puppet::Functions::Function3x
Constants
- PARAM_NAMES
Table of optimized parameter names - 0 to 5 parameters
Public Class Methods
create_function(func_name, func_info, loader)
click to toggle source
Creates an anonymous Function3x class that wraps a 3x function
@api private
# File lib/puppet/functions.rb 698 def self.create_function(func_name, func_info, loader) 699 func_name = func_name.to_s 700 701 # Creates an anonymous class to represent the function 702 # The idea being that it is garbage collected when there are no more 703 # references to it. 704 # 705 # (Do not give the class the block here, as instance variables should be set first) 706 the_class = Class.new(Function3x) 707 708 unless loader.nil? 709 the_class.instance_variable_set(:'@loader', loader.private_loader) 710 end 711 712 the_class.instance_variable_set(:'@func_name', func_name) 713 the_class.instance_variable_set(:'@method3x', :"function_#{func_name}") 714 715 # Make the anonymous class appear to have the class-name <func_name> 716 # Even if this class is not bound to such a symbol in a global ruby scope and 717 # must be resolved via the loader. 718 # This also overrides any attempt to define a name method in the given block 719 # (Since it redefines it) 720 # 721 the_class.instance_eval do 722 def name 723 @func_name 724 end 725 726 def loader 727 @loader 728 end 729 730 def method3x 731 @method3x 732 end 733 end 734 735 # Add the method that is called - it simply delegates to 736 # the 3.x function by calling it via the calling scope using the @method3x symbol 737 # :"function_#{name}". 738 # 739 # When function is not an rvalue function, make sure it produces nil 740 # 741 the_class.class_eval do 742 743 # Bypasses making the call via the dispatcher to make sure errors 744 # are reported exactly the same way as in 3x. The dispatcher is still needed as it is 745 # used to support other features than calling. 746 # 747 def call(scope, *args, &block) 748 begin 749 result = catch(:return) do 750 mapped_args = Puppet::Pops::Evaluator::Runtime3FunctionArgumentConverter.map_args(args, scope, '') 751 # this is the scope.function_xxx(...) call 752 return scope.send(self.class.method3x, mapped_args) 753 end 754 return result.value 755 rescue Puppet::Pops::Evaluator::Next => jumper 756 begin 757 throw :next, jumper.value 758 rescue Puppet::Parser::Scope::UNCAUGHT_THROW_EXCEPTION 759 raise Puppet::ParseError.new("next() from context where this is illegal", jumper.file, jumper.line) 760 end 761 rescue Puppet::Pops::Evaluator::Return => jumper 762 begin 763 throw :return, jumper 764 rescue Puppet::Parser::Scope::UNCAUGHT_THROW_EXCEPTION 765 raise Puppet::ParseError.new("return() from context where this is illegal", jumper.file, jumper.line) 766 end 767 end 768 end 769 end 770 771 # Create a dispatcher based on func_info 772 type, names = Puppet::Functions.any_signature(*from_to_names(func_info)) 773 last_captures_rest = (type.size_range[1] == Float::INFINITY) 774 775 # The method '3x_function' here is a dummy as the dispatcher is not used for calling, only for information. 776 the_class.dispatcher.add(Puppet::Pops::Functions::Dispatch.new(type, '3x_function', names, last_captures_rest)) 777 # The function class is returned as the result of the create function method 778 the_class 779 end
from_to_names(func_info)
click to toggle source
Compute min and max number of arguments and a list of constructed parameter names p0 - pn (since there are no parameter names in 3x functions).
@api private
# File lib/puppet/functions.rb 785 def self.from_to_names(func_info) 786 arity = func_info[:arity] 787 if arity.nil? 788 arity = -1 789 end 790 if arity < 0 791 from = -arity - 1 # arity -1 is 0 min param, -2 is min 1 param 792 to = :default # infinite range 793 count = -arity # the number of named parameters 794 else 795 count = from = to = arity 796 end 797 # Names of parameters, up to 5 are optimized and use frozen version 798 # Note that (0..count-1) produces expected empty array for count == 0, 0-n for count >= 1 799 names = count <= 5 ? PARAM_NAMES[count] : (0..count-1).map {|n| "p#{n}" } 800 [from, to, names] 801 end
Public Instance Methods
call(scope, *args, &block)
click to toggle source
Bypasses making the call via the dispatcher to make sure errors are reported exactly the same way as in 3x. The dispatcher is still needed as it is used to support other features than calling.
# File lib/puppet/functions.rb 747 def call(scope, *args, &block) 748 begin 749 result = catch(:return) do 750 mapped_args = Puppet::Pops::Evaluator::Runtime3FunctionArgumentConverter.map_args(args, scope, '') 751 # this is the scope.function_xxx(...) call 752 return scope.send(self.class.method3x, mapped_args) 753 end 754 return result.value 755 rescue Puppet::Pops::Evaluator::Next => jumper 756 begin 757 throw :next, jumper.value 758 rescue Puppet::Parser::Scope::UNCAUGHT_THROW_EXCEPTION 759 raise Puppet::ParseError.new("next() from context where this is illegal", jumper.file, jumper.line) 760 end 761 rescue Puppet::Pops::Evaluator::Return => jumper 762 begin 763 throw :return, jumper 764 rescue Puppet::Parser::Scope::UNCAUGHT_THROW_EXCEPTION 765 raise Puppet::ParseError.new("return() from context where this is illegal", jumper.file, jumper.line) 766 end 767 end 768 end
loader()
click to toggle source
# File lib/puppet/functions.rb 726 def loader 727 @loader 728 end
method3x()
click to toggle source
# File lib/puppet/functions.rb 730 def method3x 731 @method3x 732 end
name()
click to toggle source
# File lib/puppet/functions.rb 722 def name 723 @func_name 724 end