# class Puppet::Type

The base class for all Puppet types.

A type describes:

### Public Class Methods

allattrs() click to toggle source

Returns all the attribute names of the type in the appropriate order. The {key_attributes} come first, then the {provider}, then the {properties}, and finally the {parameters} and {metaparams}, all in the order they were specified in the respective files. @return [Array<String>] all type attribute names in a defined order.

    # File lib/puppet/type.rb, line 117
    def self.allattrs
      key_attributes | (parameters & [:provider]) | properties.collect { |property| property.name } | parameters | metaparams
    end

apply_to() click to toggle source

Makes this type apply to `:host` if not already applied to something else. @return [Symbol] a `:device`, `:host`, or `:both` enumeration @api private

    # File lib/puppet/type.rb, line 245
    def self.apply_to
      @apply_to ||= :host
    end

apply_to_all() click to toggle source

Makes this type applicable to `:both` (i.e. `:host` and `:device`). @return [Symbol] Returns `:both` @api private

    # File lib/puppet/type.rb, line 238
    def self.apply_to_all
      @apply_to = :both
    end

apply_to_device() click to toggle source

@comment These `apply_to` methods are horrible. They should really be implemented

    as part of the usual system of constraints that apply to a type and
    provider pair, but were implemented as a separate shadow system.

@comment We should rip them out in favour of a real constraint pattern around the

    target device - whatever that looks like - and not have this additional
    magic here. --daniel 2012-03-08

Makes this type applicable to `:device`. @return [Symbol] Returns `:device` @api private

    # File lib/puppet/type.rb, line 222
    def self.apply_to_device
      @apply_to = :device
    end

apply_to_host() click to toggle source

Makes this type applicable to `:host`. @return [Symbol] Returns `:host` @api private

    # File lib/puppet/type.rb, line 230
    def self.apply_to_host
      @apply_to = :host
    end

attrclass(name) click to toggle source

Returns the class associated with the given attribute name. @param name [String] the name of the attribute to obtain the class for @return [Class, nil] the class for the given attribute, or nil if the name does not refer to an existing attribute

    # File lib/puppet/type.rb, line 125
    def self.attrclass(name)
      @attrclasses ||= {}

      # We cache the value, since this method gets called such a huge number
      # of times (as in, hundreds of thousands in a given run).
      unless @attrclasses.include?(name)
        @attrclasses[name] = case self.attrtype(name)
        when :property; @validproperties[name]
        when :meta; @@metaparamhash[name]
        when :param; @paramhash[name]
        end
      end
      @attrclasses[name]
    end

attrtype(attr) click to toggle source

Returns the attribute type (`:property`, `;param`, `:meta`). @comment What type of parameter are we dealing with? Cache the results, because

    this method gets called so many times.

@return [Symbol] a symbol describing the type of attribute (`:property`, `;param`, `:meta`)

    # File lib/puppet/type.rb, line 145
    def self.attrtype(attr)
      @attrtypes ||= {}
      unless @attrtypes.include?(attr)
        @attrtypes[attr] = case
          when @validproperties.include?(attr); :property
          when @paramhash.include?(attr); :param
          when @@metaparamhash.include?(attr); :meta
          end
      end

      @attrtypes[attr]
    end

autorequire(name, &block) click to toggle source

Adds a block producing a single name (or list of names) of the given resource type name to autorequire. @example Autorequire the files File[‘foo’, ‘bar’]

    autorequire( 'file', {|| ['foo', 'bar'] })

@todo original = _“Specify a block for generating a list of objects to autorequire.

    This makes it so that you don't have to manually specify things that you clearly require."_

@param name [String] the name of a type of which one or several resources should be autorequired e.g. “file” @yield [ ] a block returning list of names of given type to auto require @yieldreturn [String, Array<String>] one or several resource names for the named type @return [void] @dsl type @api public

    # File lib/puppet/type.rb, line 1926
    def self.autorequire(name, &block)
      @autorequires ||= {}
      @autorequires[name] = block
    end

can_apply_to(target) click to toggle source

Returns true if this type is applicable to the given target. @param target [Symbol] should be :device, :host or :target, if anything else, :host is enforced @return [Boolean] true

@api private

    # File lib/puppet/type.rb, line 254
    def self.can_apply_to(target)
      [ target == :device ? :device : :host, :both ].include?(apply_to)
    end

defaultprovider() click to toggle source

The default provider, or the most suitable provider if no default provider was set. @note a warning will be issued if no default provider has been configured and a search for the most

    suitable provider returns more than one equally suitable provider.

@return [Puppet::Provider, nil] the default or most suitable provider, or nil if no provider was found

    # File lib/puppet/type.rb, line 1646
    def self.defaultprovider
      return @defaultprovider if @defaultprovider

      suitable = suitableprovider

      # Find which providers are a default for this system.
      defaults = suitable.find_all { |provider| provider.default? }

      # If we don't have any default we use suitable providers
      defaults = suitable if defaults.empty?
      max = defaults.collect { |provider| provider.specificity }.max
      defaults = defaults.find_all { |provider| provider.specificity == max }

      if defaults.length > 1
        Puppet.warning(
          "Found multiple default providers for #{self.name}: #{defaults.collect { |i| i.name.to_s }.join(", ")}; using #{defaults[0].name}"
        )
      end

      @defaultprovider = defaults.shift unless defaults.empty?
    end

doc() click to toggle source

Provides the ability to add documentation to a provider.

    # File lib/puppet/type.rb, line 1800
    def self.doc
      # Since we're mixing @doc with text from other sources, we must normalize
      # its indentation with scrub. But we don't need to manually scrub the
      # provider's doc string, since markdown_definitionlist sanitizes its inputs.
      scrub(@doc) + "Available providers are:\n\n" + parenttype.providers.sort { |a,b|
        a.to_s <=> b.to_s
      }.collect { |i|
        markdown_definitionlist( i, scrub(parenttype().provider(i).doc) )
      }.join
    end

eachautorequire() { |type, block| ... } click to toggle source

Provides iteration over added auto-requirements (see {autorequire}). @yieldparam type [String] the name of the type to autoriquire an instance of @yieldparam block [Proc] a block producing one or several dependencies to auto require (see {autorequire}). @yieldreturn [void] @return [void]

    # File lib/puppet/type.rb, line 1936
    def self.eachautorequire
      @autorequires ||= {}
      @autorequires.each { |type, block|
        yield(type, block)
      }
    end

eachmetaparam() { |name| ... } click to toggle source

Provides iteration over meta-parameters. @yieldparam p [Puppet::Parameter] each meta parameter @return [void]

    # File lib/puppet/type.rb, line 162
    def self.eachmetaparam
      @@metaparams.each { |p| yield p.name }
    end

ensurable(&block) click to toggle source

Creates a new `ensure` property with configured default values or with configuration by an optional block. This method is a convenience method for creating a property `ensure` with default accepted values. If no block is specified, the new `ensure` property will accept the default symbolic values `:present`, and `:absent` - see {Puppet::Property::Ensure}. If something else is wanted, pass a block and make calls to {Puppet::Property.newvalue} from this block to define each possible value. If a block is passed, the defaults are not automatically added to the set of valid values.

@note This method will be automatically called without a block if the type implements the methods

    specified by {ensurable?}. It is recommended to always call this method and not rely on this automatic
    specification to clearly state that the type is ensurable.

@overload ensurable() @overload ensurable({|| … }) @yield [ ] A block evaluated in scope of the new Parameter @yieldreturn [void] @return [void] @dsl type @api public

    # File lib/puppet/type.rb, line 186
    def self.ensurable(&block)
      if block_given?
        self.newproperty(:ensure, :parent => Puppet::Property::Ensure, &block)
      else
        self.newproperty(:ensure, :parent => Puppet::Property::Ensure) do
          self.defaultvalues
        end
      end
    end

ensurable?() click to toggle source

Returns true if the type implements the default behavior expected by being ensurable “by default”. A type is ensurable by default if it responds to `:exists`, `:create`, and `:destroy`. If a type implements these methods and have not already specified that it is ensurable, it will be made so with the defaults specified in {ensurable}. @return [Boolean] whether the type is ensurable or not.

    # File lib/puppet/type.rb, line 202
    def self.ensurable?
      # If the class has all three of these methods defined, then it's
      # ensurable.
      [:exists?, :create, :destroy].all? { |method|
        self.public_method_defined?(method)
      }
    end

handle_param_options(name, options) click to toggle source

Processes the options for a named parameter. @param name [String] the name of a parameter @param options [Hash] a hash of options @option options [Boolean] :boolean if option set to true, an access method on the form name? is added for the param @return [void]

    # File lib/puppet/type.rb, line 264
    def self.handle_param_options(name, options)
      # If it's a boolean parameter, create a method to test the value easily
      if options[:boolean]
        define_method(name.to_s + "?") do
          val = self[name]
          if val == :true or val == true
            return true
          end
        end
      end
    end

hash2resource(hash) click to toggle source

Converts a simple hash into a Resource instance. @todo as opposed to a complex hash? Other raised exceptions? @param [Hash{Symbol, String => Object}] resource attribute to value map to initialize the created resource from @return [Puppet::Resource] the resource created from the hash @raise [Puppet::Error] if a title is missing in the given hash

    # File lib/puppet/type.rb, line 1144
    def self.hash2resource(hash)
      hash = hash.inject({}) { |result, ary| result[ary[0].to_sym] = ary[1]; result }

      title = hash.delete(:title)
      title ||= hash[:name]
      title ||= hash[key_attributes.first] if key_attributes.length == 1

      raise Puppet::Error, "Title or name must be provided" unless title

      # Now create our resource.
      resource = Puppet::Resource.new(self.name, title)
      [:catalog].each do |attribute|
        if value = hash[attribute]
          hash.delete(attribute)
          resource.send(attribute.to_s + "=", value)
        end
      end

      hash.each do |param, value|
        resource[param] = value
      end
      resource
    end

initvars() click to toggle source

Initializes all of the variables that must be initialized for each subclass. @todo Does the explanation make sense? @return [void]

    # File lib/puppet/type.rb, line 2056
    def self.initvars
      # all of the instances of this class
      @objects = Hash.new
      @aliases = Hash.new

      @defaults = {}

      @parameters ||= []

      @validproperties = {}
      @properties = []
      @parameters = []
      @paramhash = {}

      @paramdoc = Hash.new { |hash,key|
        key = key.intern if key.is_a?(String)
        if hash.include?(key)
          hash[key]
        else
          "Param Documentation for #{key} not found"
        end
      }

      @doc ||= ""

    end

instances() click to toggle source

Retrieves all known instances. @todo Retrieves them from where? Known to whom? Either requires providers or must be overridden. @raise [Puppet::DevError] when there are no providers and the implementation has not overridded this method.

    # File lib/puppet/type.rb, line 1094
    def self.instances
      raise Puppet::DevError, "#{self.name} has no providers and has not overridden 'instances'" if provider_hash.empty?

      # Put the default provider first, then the rest of the suitable providers.
      provider_instances = {}
      providers_by_source.collect do |provider|
        all_properties = self.properties.find_all do |property|
          provider.supports_parameter?(property)
        end.collect do |property|
          property.name
        end

        provider.instances.collect do |instance|
          # We always want to use the "first" provider instance we find, unless the resource
          # is already managed and has a different provider set
          if other = provider_instances[instance.name]
            Puppet.debug "%s %s found in both %s and %s; skipping the %s version" %
              [self.name.to_s.capitalize, instance.name, other.class.name, instance.class.name, instance.class.name]
            next
          end
          provider_instances[instance.name] = instance

          result = new(:name => instance.name, :provider => instance)
          properties.each { |name| result.newattr(name) }
          result
        end
      end.flatten.compact
    end

isomorphic?() click to toggle source

Returns true if the type’s notion of name is the identity of a resource. See the overview of this class for a longer explanation of the concept isomorphism. Defaults to true.

@return [Boolan] true, if this type’s name is isomorphic with the object

    # File lib/puppet/type.rb, line 862
    def self.isomorphic?
      if defined?(@isomorphic)
        return @isomorphic
      else
        return true
      end
    end

key_attribute_parameters() click to toggle source

Returns parameters that act as a key. All parameters that return true from isnamevar? or is named `:name` are included in the returned result. @todo would like a better explanation @return Array<??? Puppet::Parameter>

    # File lib/puppet/type.rb, line 359
    def self.key_attribute_parameters
      @key_attribute_parameters ||= (
        params = @parameters.find_all { |param|
          param.isnamevar? or param.name == :name
        }
      )
    end

key_attributes() click to toggle source

Returns cached {key_attribute_parameters} names @todo what is a ‘key_attribute’ ? @return [Array<String>] cached key_attribute names

    # File lib/puppet/type.rb, line 371
    def self.key_attributes
      # This is a cache miss around 0.05 percent of the time. --daniel 2012-07-17
      @key_attributes_cache ||= key_attribute_parameters.collect { |p| p.name }
    end

metaparam?(param) click to toggle source

Is the given parameter a meta-parameter? @return [Boolean] true if the given parameter is a meta-parameter.

    # File lib/puppet/type.rb, line 279
    def self.metaparam?(param)
      @@metaparamhash.include?(param.intern)
    end

metaparamclass(name) click to toggle source

Returns the meta-parameter class associated with the given meta-parameter name. Accepts a `nil` name, and return nil. @param name [String, nil] the name of a meta-parameter @return [Class,nil] the class for the given meta-parameter, or `nil` if no such meta-parameter exists, (or if

    the given meta-parameter name is `nil`.

    # File lib/puppet/type.rb, line 289
    def self.metaparamclass(name)
      return nil if name.nil?
      @@metaparamhash[name.intern]
    end

metaparamdoc(metaparam) click to toggle source

Returns the documentation for a given meta-parameter of this type. @todo the type for the param metaparam @param metaparam [??? Puppet::Parameter] the meta-parameter to get documentation for. @return [String] the documentation associated with the given meta-parameter, or nil of not such documentation

    exists.

@raises [?] if the given metaparam is not a meta-parameter in this type

    # File lib/puppet/type.rb, line 308
    def self.metaparamdoc(metaparam)
      @@metaparamhash[metaparam].doc
    end

metaparams() click to toggle source

Returns all meta-parameter names. @return [Array<String>] all meta-parameter names

    # File lib/puppet/type.rb, line 297
    def self.metaparams
      @@metaparams.collect { |param| param.name }
    end

new(resource) click to toggle source

Creates an instance of Type from a hash or a {Puppet::Resource}. @todo Unclear if this is a new Type or a new instance of a given type (the initialization ends

    with calling validate - which seems like validation of an instance of a given type, not a new
    meta type.

@todo Explain what the Hash and Resource are. There seems to be two different types of

    resources; one that causes the title to be set to resource.title, and one that
    causes the title to be resource.ref ("for components") - what is a component?

@overaload initialize(hsh)

    @param hsh [Hash]

@overload initialize(resource)

    @param resource [Puppet:Resource]

    # File lib/puppet/type.rb, line 2167
    def initialize(resource)
      resource = self.class.hash2resource(resource) unless resource.is_a?(Puppet::Resource)

      # The list of parameter/property instances.
      @parameters = {}

      # Set the title first, so any failures print correctly.
      if resource.type.to_s.downcase.to_sym == self.class.name
        self.title = resource.title
      else
        # This should only ever happen for components
        self.title = resource.ref
      end

      [:file, :line, :catalog, :exported, :virtual].each do |getter|
        setter = getter.to_s + "="
        if val = resource.send(getter)
          self.send(setter, val)
        end
      end

      @tags = resource.tags

      @original_parameters = resource.to_hash

      set_name(@original_parameters)

      set_default(:provider)

      set_parameters(@original_parameters)

      self.validate if self.respond_to?(:validate)
    end

newmetaparam(name, options = {}, &block) click to toggle source

Creates a new meta-parameter. This creates a new meta-parameter that is added to all types. @param name [Symbol] the name of the parameter @param options [Hash] a hash with options. @option options [Class<inherits Puppet::Parameter>] :parent (Puppet::Parameter) the super class of this parameter @option options [Hash{String => Object}] :attributes a hash that is applied to the generated class

    by calling setter methods corresponding to this hash's keys/value pairs. This is done before the given
    block is evaluated.

@option options [Boolean] :boolean (false) specifies if this is a boolean parameter @option options [Boolean] :namevar (false) specifies if this parameter is the namevar @option options [Symbol, Array<Symbol>] :required_features specifies required provider features by name @return [Class<inherits Puppet::Parameter>] the created parameter @yield [ ] a required block that is evaluated in the scope of the new meta-parameter @api public @dsl type @todo Verify that this description is ok

    # File lib/puppet/type.rb, line 329
    def self.newmetaparam(name, options = {}, &block)
      @@metaparams ||= []
      @@metaparamhash ||= {}
      name = name.intern

      param = genclass(
        name,
        :parent => options[:parent] || Puppet::Parameter,
        :prefix => "MetaParam",
        :hash => @@metaparamhash,
        :array => @@metaparams,
        :attributes => options[:attributes],
        &block
      )

      # Grr.
      param.required_features = options[:required_features] if options[:required_features]

      handle_param_options(name, options)

      param.metaparam = true

      param
    end

newparam(name, options = {}, &block) click to toggle source

Creates a new parameter. @param name [Symbol] the name of the parameter @param options [Hash] a hash with options. @option options [Class<inherits Puppet::Parameter>] :parent (Puppet::Parameter) the super class of this parameter @option options [Hash{String => Object}] :attributes a hash that is applied to the generated class

    by calling setter methods corresponding to this hash's keys/value pairs. This is done before the given
    block is evaluated.

@option options [Boolean] :boolean (false) specifies if this is a boolean parameter @option options [Boolean] :namevar (false) specifies if this parameter is the namevar @option options [Symbol, Array<Symbol>] :required_features specifies required provider features by name @return [Class<inherits Puppet::Parameter>] the created parameter @yield [ ] a required block that is evaluated in the scope of the new parameter @api public @dsl type

    # File lib/puppet/type.rb, line 437
    def self.newparam(name, options = {}, &block)
      options[:attributes] ||= {}

      param = genclass(
        name,
        :parent     => options[:parent] || Puppet::Parameter,
        :attributes => options[:attributes],
        :block      => block,
        :prefix     => "Parameter",
        :array      => @parameters,
        :hash       => @paramhash
      )

      handle_param_options(name, options)

      # Grr.
      param.required_features = options[:required_features] if options[:required_features]

      param.isnamevar if options[:namevar]

      param
    end

newproperty(name, options = {}, &block) click to toggle source

Creates a new property. @param name [Symbol] the name of the property @param options [Hash] a hash with options. @option options [Symbol] :array_matching (:first) specifies how the current state is matched against

    the wanted state. Use `:first` if the property is single valued, and (`:all`) otherwise.

@option options [Class<inherits Puppet::Property>] :parent (Puppet::Property) the super class of this property @option options [Hash{String => Object}] :attributes a hash that is applied to the generated class

    by calling setter methods corresponding to this hash's keys/value pairs. This is done before the given
    block is evaluated.

@option options [Boolean] :boolean (false) specifies if this is a boolean parameter @option options [Symbol] :retrieve the method to call on the provider (or `parent` if `provider` is not set)

    to retrieve the current value of this property.

@option options [Symbol, Array<Symbol>] :required_features specifies required provider features by name @return [Class<inherits Puppet::Property>] the created property @yield [ ] a required block that is evaluated in the scope of the new property @api public @dsl type

    # File lib/puppet/type.rb, line 478
    def self.newproperty(name, options = {}, &block)
      name = name.intern

      # This is here for types that might still have the old method of defining
      # a parent class.
      unless options.is_a? Hash
        raise Puppet::DevError,
          "Options must be a hash, not #{options.inspect}"
      end

      raise Puppet::DevError, "Class #{self.name} already has a property named #{name}" if @validproperties.include?(name)

      if parent = options[:parent]
        options.delete(:parent)
      else
        parent = Puppet::Property
      end

      # We have to create our own, new block here because we want to define
      # an initial :retrieve method, if told to, and then eval the passed
      # block if available.
      prop = genclass(name, :parent => parent, :hash => @validproperties, :attributes => options) do
        # If they've passed a retrieve method, then override the retrieve
        # method on the class.
        if options[:retrieve]
          define_method(:retrieve) do
            provider.send(options[:retrieve])
          end
        end

        class_eval(&block) if block
      end

      # If it's the 'ensure' property, always put it first.
      if name == :ensure
        @properties.unshift prop
      else
        @properties << prop
      end

      prop
    end

paramclass(name) click to toggle source

@return [Puppet::Parameter] Returns the parameter class associated with the given parameter name.

    # File lib/puppet/type.rb, line 532
    def self.paramclass(name)
      @paramhash[name]
    end

paramdoc(param) click to toggle source

    # File lib/puppet/type.rb, line 521
    def self.paramdoc(param)
      @paramhash[param].doc
    end

parameters() click to toggle source

@return [Array<String>] Returns the parameter names

    # File lib/puppet/type.rb, line 526
    def self.parameters
      return [] unless defined?(@parameters)
      @parameters.collect { |klass| klass.name }
    end

propertybyname(name) click to toggle source

@return [Puppet::Property] Returns the property class ??? associated with the given property name

    # File lib/puppet/type.rb, line 537
    def self.propertybyname(name)
      @validproperties[name]
    end

provide(name, options = {}, &block) click to toggle source

Creates a new provider of a type. This method must be called directly on the type that it’s implementing. @todo Fix Confusing Explanations!

    Is this a new provider of a Type (metatype), or a provider of an instance of Type (a resource), or
    a Provider (the implementation of a Type's behavior). CONFUSED. It calls magically named methods like
    "providify" ...

@param name [String, Symbol] the name of the WHAT? provider? type? @param options [Hash{Symbol => Object}] a hash of options, used by this method, and passed on to {#genclass}, (see

    it for additional options to pass).

@option options [Puppet::Provider] :parent the parent provider (what is this?) @option options [Puppet::Type] :resource_type the resource type, defaults to this type if unspecified @return [Puppet::Provider] a provider ??? @raise [Puppet::DevError] when the parent provider could not be found.

    # File lib/puppet/type.rb, line 1731
    def self.provide(name, options = {}, &block)
      name = name.intern

      if unprovide(name)
        Puppet.debug "Reloading #{name} #{self.name} provider"
      end

      parent = if pname = options[:parent]
        options.delete(:parent)
        if pname.is_a? Class
          pname
        else
          if provider = self.provider(pname)
            provider
          else
            raise Puppet::DevError,
              "Could not find parent provider #{pname} of #{name}"
          end
        end
      else
        Puppet::Provider
      end

      options[:resource_type] ||= self

      self.providify

      provider = genclass(
        name,
        :parent     => parent,
        :hash       => provider_hash,
        :prefix     => "Provider",
        :block      => block,
        :include    => feature_module,
        :extend     => feature_module,
        :attributes => options
      )

      provider
    end

provider(name) click to toggle source

Returns the provider having the given name. This will load a provider if it is not already loaded. The returned provider is the first found provider having the given name, where “first found” semantics is defined by the {providerloader} in use.

@param name [String] the name of the provider to get @return [Puppet::Provider, nil] the found provider, or nil if no provider of the given name was found

    # File lib/puppet/type.rb, line 1688
    def self.provider(name)
      name = name.intern

      # If we don't have it yet, try loading it.
      @providerloader.load(name) unless provider_hash.has_key?(name)
      provider_hash[name]
    end

provider_hash() click to toggle source

@return [Hash{ ??? => Puppet::Provider}] Returns a hash of WHAT EXACTLY for this type. @see ::provider_hash_by_type method to get the same for some other type

    # File lib/puppet/type.rb, line 1677
    def self.provider_hash
      Puppet::Type.provider_hash_by_type(self.name)
    end

provider_hash_by_type(type) click to toggle source

@return [Hash{??? => Puppet::Provider}] Returns a hash of WHAT EXACTLY for the given type @todo what goes into this hash?

    # File lib/puppet/type.rb, line 1670
    def self.provider_hash_by_type(type)
      @provider_hashes ||= {}
      @provider_hashes[type] ||= {}
    end

providers() click to toggle source

Returns a list of loaded providers by name. This method will not load/search for available providers. @return [Array<String>] list of loaded provider names

    # File lib/puppet/type.rb, line 1700
    def self.providers
      provider_hash.keys
    end

providers_by_source() click to toggle source

Returns a list of one suitable provider per source, with the default provider first. @todo Needs better explanation; what does “source” mean in this context? @return [Array<Puppet::Provider>] list of providers

    # File lib/puppet/type.rb, line 1127
    def self.providers_by_source
      # Put the default provider first (can be nil), then the rest of the suitable providers.
      sources = []
      [defaultprovider, suitableprovider].flatten.uniq.collect do |provider|
        next if provider.nil?
        next if sources.include?(provider.source)

        sources << provider.source
        provider
      end.compact
    end

providify() click to toggle source

Ensures there is a `:provider` parameter defined. Should only be called if there are providers. @return [void]

    # File lib/puppet/type.rb, line 1775
    def self.providify
      return if @paramhash.has_key? :provider

      newparam(:provider) do
        # We're using a hacky way to get the name of our type, since there doesn't
        # seem to be a correct way to introspect this at the time this code is run.
        # We expect that the class in which this code is executed will be something
        # like Puppet::Type::Ssh_authorized_key::ParameterProvider.
        desc <<-EOT
          The specific backend to use for this `#{self.to_s.split('::')[2].downcase}`
          resource. You will seldom need to specify this --- Puppet will usually
          discover the appropriate provider for your platform.
        EOT

        # This is so we can refer back to the type to get a list of
        # providers for documentation.
        class << self
          # The reference to a parent type for the parameter `:provider` used to get a list of
          # providers for documentation purposes.
          #
          attr_accessor :parenttype
        end

        # Provides the ability to add documentation to a provider.
        #
        def self.doc
          # Since we're mixing @doc with text from other sources, we must normalize
          # its indentation with scrub. But we don't need to manually scrub the
          # provider's doc string, since markdown_definitionlist sanitizes its inputs.
          scrub(@doc) + "Available providers are:\n\n" + parenttype.providers.sort { |a,b|
            a.to_s <=> b.to_s
          }.collect { |i|
            markdown_definitionlist( i, scrub(parenttype().provider(i).doc) )
          }.join
        end

        # @todo this does what? where and how?
        # @returns [String] the name of the provider
        defaultto {
          prov = @resource.class.defaultprovider
          prov.name if prov
        }

        validate do |provider_class|
          provider_class = provider_class[0] if provider_class.is_a? Array
          provider_class = provider_class.class.name if provider_class.is_a?(Puppet::Provider)

          unless provider = @resource.class.provider(provider_class)
            raise ArgumentError, "Invalid #{@resource.class.name} provider '#{provider_class}'"
          end
        end

        munge do |provider|
          provider = provider[0] if provider.is_a? Array
          provider = provider.intern if provider.is_a? String
          @resource.provider = provider

          if provider.is_a?(Puppet::Provider)
            provider.class.name
          else
            provider
          end
        end
      end.parenttype = self
    end

relationship_params() click to toggle source

@todo document this, have no clue what this does… it retuns “RelationshipMetaparam.subclasses”

    # File lib/puppet/type.rb, line 1469
    def self.relationship_params
      RelationshipMetaparam.subclasses
    end

suitableprovider() click to toggle source

Returns a list of suitable providers for the given type. A call to this method will load all providers if not already loaded and ask each if it is suitable - those that are are included in the result. @note This method also does some special processing which rejects a provider named `:fake` (for testing purposes). @return [Array<Puppet::Provider>] Returns an array of all suitable providers.

    # File lib/puppet/type.rb, line 1858
    def self.suitableprovider
      providerloader.loadall if provider_hash.empty?
      provider_hash.find_all { |name, provider|
        provider.suitable?
      }.collect { |name, provider|
        provider
      }.reject { |p| p.name == :fake } # For testing
    end

title_patterns() click to toggle source

Returns a mapping from the title string to setting of attribute value(s). This default implementation provides a mapping of title to the one and only namevar present in the type’s definition. @note Advanced: some logic requires this mapping to be done differently, using a different

    validation/pattern, breaking up the title
    into several parts assigning each to an individual attribute, or even use a composite identity where
    all namevars are seen as part of the unique identity (such computation is done by the {#uniqueness} method.
    These advanced options are rarely used (only one of the built in puppet types use this, and then only
    a small part of the available functionality), and the support for these advanced mappings is not
    implemented in a straight forward way. For these reasons, this method has been marked as private).

@raise [Puppet::DevError] if there is no title pattern and there are two or more key attributes @return [Array<Array<Regexp, Array<Array <Symbol, Proc>>>>, nil] a structure with a regexp and the first key_attribute ??? @comment This wonderful piece of logic creates a structure used by Resource.parse_title which

    has the capability to assign parts of the title to one or more attributes; It looks like an implementation
    of a composite identity key (all parts of the key_attributes array are in the key). This can also
    be seen in the method uniqueness_key.
    The implementation in this method simply assigns the title to the one and only namevar (which is name
    or a variable marked as namevar).
    If there are multiple namevars (any in addition to :name?) then this method MUST be implemented
    as it raises an exception if there is more than 1. Note that in puppet, it is only File that uses this
    to create a different pattern for assigning to the :path attribute
    This requires further digging.
    The entire construct is somewhat strange, since resource checks if the method "title_patterns" is
    implemented (it seems it always is) - why take this more expensive regexp mathching route for all
    other types?

@api private

    # File lib/puppet/type.rb, line 404
    def self.title_patterns
      case key_attributes.length
      when 0; []
      when 1;
        [ [ /(.*)/m, [ [key_attributes.first] ] ] ]
      else
        raise Puppet::DevError,"you must specify title patterns when there are two or more key attributes"
      end
    end

to_s() click to toggle source

Returns the name of this type (if specified) or the parent type to_s. The returned name is on the form “Puppet::Type::<name>”, where the first letter of name is capitalized. @return [String] the fully qualified name Puppet::Type::<name> where the first letter of name is captialized

Calls superclass method Object#to_s

    # File lib/puppet/type.rb, line 2088
    def self.to_s
      if defined?(@name)
        "Puppet::Type::#{@name.to_s.capitalize}"
      else
        super
      end
    end

unprovide(name) click to toggle source

@todo this needs a better explanation Removes the implementation class of a given provider. @return [Object] returns what {Puppet::Util::ClassGen#rmclass} returns

    # File lib/puppet/type.rb, line 1844
    def self.unprovide(name)
      if @defaultprovider and @defaultprovider.name == name
        @defaultprovider = nil
      end

      rmclass(name, :hash => provider_hash, :prefix => "Provider")
    end

valid_parameter?(name) click to toggle source

(see validattr?) @note see comment in code - how should this be documented? Are some of the other query methods deprecated?

    (or should be).

@comment This is a forward-compatibility method - it’s the validity interface we’ll use in Puppet::Resource.

    # File lib/puppet/type.rb, line 582
    def self.valid_parameter?(name)
      validattr?(name)
    end

validate(&block) click to toggle source

Creates a `validate` method that is used to validate a resource before it is operated on. The validation should raise exceptions if the validation finds errors. (It is not recommended to issue warnings as this typically just ends up in a logfile - you should fail if a validation fails). The easiest way to raise an appropriate exception is to call the method {Puppet::Util::Errors.fail} with the message as an argument.

@yield [ ] a required block called with self set to the instance of a Type class representing a resource. @return [void] @dsl type @api public

    # File lib/puppet/type.rb, line 2107
    def self.validate(&block)
      define_method(:validate, &block)
      #@validate = block
    end

validattr?(name) click to toggle source

Returns whether or not the given name is the name of a property, parameter or meta-parameter @return [Boolean] true if the given attribute name is the name of an existing property, parameter or meta-parameter

    # File lib/puppet/type.rb, line 544
    def self.validattr?(name)
      name = name.intern
      return true if name == :name
      @validattrs ||= {}

      unless @validattrs.include?(name)
        @validattrs[name] = !!(self.validproperty?(name) or self.validparameter?(name) or self.metaparam?(name))
      end

      @validattrs[name]
    end

validparameter?(name) click to toggle source

@return [Boolean] Returns true if the given name is the name of an existing parameter

    # File lib/puppet/type.rb, line 573
    def self.validparameter?(name)
      raise Puppet::DevError, "Class #{self} has not defined parameters" unless defined?(@parameters)
      !!(@paramhash.include?(name) or @@metaparamhash.include?(name))
    end

validproperties() click to toggle source

@return [Array<Symbol>, {}] Returns a list of valid property names, or an empty hash if there are none. @todo An empty hash is returned if there are no defined parameters (not an empty array). This looks like

    a bug.

    # File lib/puppet/type.rb, line 566
    def self.validproperties
      return {} unless defined?(@parameters)

      @validproperties.keys
    end

validproperty?(name) click to toggle source

@return [Boolean] Returns true if the given name is the name of an existing property

    # File lib/puppet/type.rb, line 557
    def self.validproperty?(name)
      name = name.intern
      @validproperties.include?(name) && @validproperties[name]
    end

validprovider?(name) click to toggle source

Returns true if the given name is a reference to a provider and if this is a suitable provider for this type. @todo How does the provider know if it is suitable for the type? Is it just suitable for the platform/

    environment where this method is executing?

@param name [String] the name of the provider for which validity is checked @return [Boolean] true if the given name references a provider that is suitable

    # File lib/puppet/type.rb, line 1711
    def self.validprovider?(name)
      name = name.intern

      (provider_hash.has_key?(name) && provider_hash[name].suitable?)
    end

### Public Instance Methods

<=>(other) click to toggle source

Compares this type against the given other (type) and returns -1, 0, or +1 depending on the order. @param other [Object] the object to compare against (produces nil, if not kind of Type} @return [-1, 0, +1, nil] produces -1 if this type is before the given other type, 0 if equals, and 1 if after.

    Returns nil, if the given _other_ is not a kind of Type.

@see Comparable

    # File lib/puppet/type.rb, line 93
    def <=>(other)
      # We only order against other types, not arbitrary objects.
      return nil unless other.is_a? Puppet::Type
      # Our natural order is based on the reference name we use when comparing
      # against other type instances.
      self.ref <=> other.ref
    end

[](name) click to toggle source

Gets the ‘should’ (wanted state) value of a parameter or property by name. To explicitly get the ‘is’ (current state) value use `o.is(:name)`, and to explicitly get the ‘should’ value use `o.should(:name)` @param name [String] the name of the attribute to obtain the ‘should’ value for. @return [Object] ‘should’/wanted value of the given attribute

    # File lib/puppet/type.rb, line 619
    def [](name)
      name = name.intern
      fail("Invalid parameter #{name}(#{name.inspect})") unless self.class.validattr?(name)

      if name == :name && nv = name_var
        name = nv
      end

      if obj = @parameters[name]
        # Note that if this is a property, then the value is the "should" value,
        # not the current value.
        obj.value
      else
        return nil
      end
    end

[]=(name,value) click to toggle source

Sets the ‘should’ (wanted state) value of a property, or the value of a parameter. @return @raise [Puppet::Error] if the setting of the value fails, or if the given name is nil.

    # File lib/puppet/type.rb, line 639
    def []=(name,value)
      name = name.intern

      fail("Invalid parameter #{name}") unless self.class.validattr?(name)

      if name == :name && nv = name_var
        name = nv
      end
      raise Puppet::Error.new("Got nil value for #{name}") if value.nil?

      property = self.newattr(name)

      if property
        begin
          # make sure the parameter doesn't have any errors
          property.value = value
        rescue => detail
          error = Puppet::Error.new("Parameter #{name} failed on #{ref}: #{detail}")
          error.set_backtrace(detail.backtrace)
          raise error
        end
      end

      nil
    end

add_property_parameter(prop_name) click to toggle source

Creates a new property value holder for the resource if it is valid and does not already exist @return [Boolean] true if a new parameter was added, false otherwise

    # File lib/puppet/type.rb, line 593
    def add_property_parameter(prop_name)
      if self.class.validproperty?(prop_name) && !@parameters[prop_name]
        self.newattr(prop_name)
        return true
      end
      false
    end

all_properties() click to toggle source

    # File lib/puppet/type.rb, line 1251
    def all_properties
      resource.class.properties.find_all do |property|
        resource.provider.nil? or resource.provider.class.supports_parameter?(property)
      end.collect do |property|
        property.name
      end
    end

ancestors() click to toggle source

Returns the ancestors - WHAT? This implementation always returns an empty list. @todo WHAT IS THIS ? @return [Array<???>] returns a list of ancestors.

    # File lib/puppet/type.rb, line 948
    def ancestors
      []
    end

appliable_to_device?() click to toggle source

@return [Boolean] Returns whether the resource is applicable to `:device` @todo Explain what this means @api private

    # File lib/puppet/type.rb, line 2403
    def appliable_to_device?
      self.class.can_apply_to(:device)
    end

appliable_to_host?() click to toggle source

@return [Boolean] Returns whether the resource is applicable to `:host` @todo Explain what this means @api private

    # File lib/puppet/type.rb, line 2410
    def appliable_to_host?
      self.class.can_apply_to(:host)
    end

autorequire(rel_catalog = nil) click to toggle source

Adds dependencies to the catalog from added autorequirements. See {autorequire} for how to add an auto-requirement. @todo needs details - see the param rel_catalog, and type of this param @param rel_catalog [Puppet::Catalog, nil] the catalog to add dependencies to. Defaults to the

    catalog (TODO: what is the type of the catalog).

@raise [Puppet::DevError] if there is no catalog

    # File lib/puppet/type.rb, line 1950
    def autorequire(rel_catalog = nil)
      rel_catalog ||= catalog
      raise(Puppet::DevError, "You cannot add relationships without a catalog") unless rel_catalog

      reqs = []
      self.class.eachautorequire { |type, block|
        # Ignore any types we can't find, although that would be a bit odd.
        next unless typeobj = Puppet::Type.type(type)

        # Retrieve the list of names from the block.
        next unless list = self.instance_eval(&block)
        list = [list] unless list.is_a?(Array)

        # Collect the current prereqs
        list.each { |dep|
          # Support them passing objects directly, to save some effort.
          unless dep.is_a? Puppet::Type
            # Skip autorequires that we aren't managing
            unless dep = rel_catalog.resource(type, dep)
              next
            end
          end

          reqs << Puppet::Relationship.new(dep, self)
        }
      }

      reqs
    end

builddepends() click to toggle source

Builds the dependencies associated with an individual object. @todo Which object is the “individual object”, as opposed to “object as a group?” or should it simply

    be "this object" as in "this resource" ?

@todo Does this method “build dependencies” or “build what it depends on” … CONFUSING

@return [Array<???>] list of WHAT? resources? edges?

    # File lib/puppet/type.rb, line 1986
    def builddepends
      # Handle the requires
      self.class.relationship_params.collect do |klass|
        if param = @parameters[klass.name]
          param.to_edges
        end
      end.flatten.reject { |r| r.nil? }
    end

currentpropvalues() click to toggle source

Returns a hash of the current properties and their values. If a resource is absent, it’s value is the symbol `:absent` @return [Hash{Puppet::Property => Object}] mapping of property instance to its value

    # File lib/puppet/type.rb, line 1050
    def currentpropvalues
      # It's important to use the 'properties' method here, as it follows the order
      # in which they're defined in the class.  It also guarantees that 'ensure'
      # is the first property, which is important for skipping 'retrieve' on
      # all the properties if the resource is absent.
      ensure_state = false
      return properties.inject({}) do | prophash, property|
        if property.name == :ensure
          ensure_state = property.retrieve
          prophash[property] = ensure_state
        else
          if ensure_state == :absent
            prophash[property] = :absent
          else
            prophash[property] = property.retrieve
          end
        end
        prophash
      end
    end

delete(attr) click to toggle source

Removes a property from the object; useful in testing or in cleanup when an error has been encountered @todo Incomprehensible - the comment says “Remove a property”, the code refers to @parameters, and

    the method parameter is called "attr" - What is it, property, parameter, both (i.e an attribute) or what?

@todo Don’t know what the attr is (name or Property/Parameter?). Guessing it is a String name… @todo Is it possible to delete a meta-parameter? @todo What does delete mean? Is it deleted from the type or is its value state ‘is’/‘should’ deleted? @param attr [String] the attribute to delete from this object. WHAT IS THE TYPE? @raise [Puppet::DecError] when an attempt is made to delete an attribute that does not exists.

    # File lib/puppet/type.rb, line 675
    def delete(attr)
      attr = attr.intern
      if @parameters.has_key?(attr)
        @parameters.delete(attr)
      else
        raise Puppet::DevError.new("Undefined attribute '#{attr}' in #{self}")
      end
    end

deleting?() click to toggle source

@return [Boolean] Returns true if the wanted state of the resoure is that it should be absent (i.e. to be deleted).

    # File lib/puppet/type.rb, line 587
    def deleting?
      obj = @parameters[:ensure] and obj.should == :absent
    end

depthfirst?() click to toggle source

Returns true if the search should be done in depth-first order. This implementation always returns false. @todo What is this used for?

@return [Boolean] true if the search should be done in depth first order.

    # File lib/puppet/type.rb, line 911
    def depthfirst?
      false
    end

eachproperty() { |property| ... } click to toggle source

Iterates over the existing properties. @todo what does this mean? As opposed to iterating over the “non existing properties” ??? Is it an

    iteration over those properties that have state? CONFUSING.

@yieldparam property [Puppet::Property] each property @return [void]

    # File lib/puppet/type.rb, line 689
    def eachproperty
      # properties is a private method
      properties.each { |property|
        yield property
      }
    end

event(options = {}) click to toggle source

Creates a transaction event. Called by Transaction or by a property. Merges the given options with the options `:resource`, `:file`, `:line`, and `:tags`, initialized from values in this object. For possible options to pass (if any ????) see {Puppet::Transaction::Event}. @todo Needs a better explanation “Why should I care who is calling this method?”, What do I need to know

    about events and how they work? Where can I read about them?

@param options [Hash] options merged with a fixed set of options defined by this method, passed on to {Puppet::Transaction::Event}. @return [Puppet::Transaction::Event] the created event

    # File lib/puppet/type.rb, line 704
    def event(options = {})
      Puppet::Transaction::Event.new({:resource => self, :file => file, :line => line, :tags => tags}.merge(options))
    end

exported?() click to toggle source

@return [Boolean] Returns whether the resource is exported or not

    # File lib/puppet/type.rb, line 2398
    def exported?; !!@exported; end

finish() click to toggle source

Finishes any outstanding processing. This method should be called as a final step in setup, to allow the parameters that have associated auto-require needs to be processed.

@todo what is the expected sequence here - who is responsible for calling this? When?

    Is the returned type correct?

@return [Array<Puppet::Parameter>] the validated list/set of attributes

    # File lib/puppet/type.rb, line 2267
    def finish
      # Make sure all of our relationships are valid.  Again, must be done
      # when the entire catalog is instantiated.
      self.class.relationship_params.collect do |klass|
        if param = @parameters[klass.name]
          param.validate_relationship
        end
      end.flatten.reject { |r| r.nil? }
    end

flush() click to toggle source

Flushes the provider if supported by the provider, else no action. This is called by the transaction. @todo What does Flushing the provider mean? Why is it interesting to know that this is

    called by the transaction? (It is not explained anywhere what a transaction is).

@return [???, nil] WHAT DOES IT RETURN? GUESS IS VOID

    # File lib/puppet/type.rb, line 958
    def flush
      self.provider.flush if self.provider and self.provider.respond_to?(:flush)
    end

insync?(is) click to toggle source

Returns true if all contained objects are in sync. @todo “contained in what?” in the given “in” parameter?

@todo deal with the comment _“FIXME I don’t think this is used on the type instances any more,

    it's really only used for testing"_

@return [Boolean] true if in sync, false otherwise.

    # File lib/puppet/type.rb, line 969
    def insync?(is)
      insync = true

      if property = @parameters[:ensure]
        unless is.include? property
          raise Puppet::DevError,
            "The is value is not in the is array for '#{property.name}'"
        end
        ensureis = is[property]
        if property.safe_insync?(ensureis) and property.should == :absent
          return true
        end
      end

      properties.each { |property|
        unless is.include? property
          raise Puppet::DevError,
            "The is value is not in the is array for '#{property.name}'"
        end

        propis = is[property]
        unless property.safe_insync?(propis)
          property.debug("Not in sync: #{propis.inspect} vs #{property.should.inspect}")
          insync = false
        #else
        #    property.debug("In sync")
        end
      }

      #self.debug("#{self} sync status is #{insync}")
      insync
    end

isomorphic?() click to toggle source

@todo check that this gets documentation (it is at the class level as well as instance). (see isomorphic?)

    # File lib/puppet/type.rb, line 872
    def isomorphic?
      self.class.isomorphic?
    end

log(msg) click to toggle source

Creates a log entry with the given message at the log level specified by the parameter `loglevel` @return [void]

    # File lib/puppet/type.rb, line 2132
    def log(msg)

      Puppet::Util::Log.create(

        :level => @parameters[:loglevel].value,
        :message => msg,

        :source => self
      )
    end

managed?() click to toggle source

Returns true if the instance is a managed instance. A ‘yes’ here means that the instance was created from the language, vs. being created in order resolve other questions, such as finding a package in a list. @note An object that is managed always stays managed, but an object that is not managed

    may become managed later in its lifecycle.

@return [Boolean] true if the object is managed

    # File lib/puppet/type.rb, line 882
    def managed?
      # Once an object is managed, it always stays managed; but an object
      # that is listed as unmanaged might become managed later in the process,
      # so we have to check that every time
      if @managed
        return @managed
      else
        @managed = false
        properties.each { |property|
          s = property.should
          if s and ! property.class.unmanaged
            @managed = true
            break
          end
        }
        return @managed
      end
    end

name() click to toggle source

@comment For now, leave the ‘name’ method functioning like it used to. Once ‘title’

    works everywhere, I'll switch it.

Returns the resource’s name @todo There is a comment in source that this is not quite the same as ‘:title’ and that a switch should

    be made...

@return [String] the name of a resource

    # File lib/puppet/type.rb, line 2283
    def name
      self[:name]
    end

name_var() click to toggle source

@return [Symbol, Boolean] Returns the name of the namevar if there is only one or false otherwise. @comment This is really convoluted and part of the support for multiple namevars (?).

    If there is only one namevar, the produced value is naturally this namevar, but if there are several?
    The logic caches the name of the namevar if it is a single name, but otherwise always
    calls key_attributes, and then caches the first if there was only one, otherwise it returns
    false and caches this (which is then subsequently returned as a cache hit).

    # File lib/puppet/type.rb, line 608
    def name_var
      return @name_var_cache unless @name_var_cache.nil?
      key_attributes = self.class.key_attributes
      @name_var_cache = (key_attributes.length == 1) && key_attributes.first
    end

newattr(name) click to toggle source

Creates an instance to represent/manage the given attribute. Requires either the attribute name or class as the first argument, then an optional hash of attributes to set during initialization. @todo The original comment is just wrong - the method does not accept a hash of options @todo Detective work required; this method interacts with provider to ask if it supports a parameter of

    the given class. it then returns the parameter if it exists, otherwise creates a parameter
     with its :resource => self.

@overload newattr(name)

    @param name [String] Unclear what name is (probably a symbol) - Needs investigation.

@overload newattr(klass)

    @param klass [Class] a class supported as an attribute class - Needs clarification what that means.

@return [???] Probably returns a new instance of the class - Needs investigation.

    # File lib/puppet/type.rb, line 728
    def newattr(name)
      if name.is_a?(Class)
        klass = name
        name = klass.name
      end

      unless klass = self.class.attrclass(name)
        raise Puppet::Error, "Resource type #{self.class.name} does not support parameter #{name}"
      end

      if provider and ! provider.class.supports_parameter?(klass)
        missing = klass.required_features.find_all { |f| ! provider.class.feature?(f) }
        debug "Provider %s does not support features %s; not managing attribute %s" % [provider.class.name, missing.join(", "), name]
        return nil
      end

      return @parameters[name] if @parameters.include?(name)

      @parameters[name] = klass.new(:resource => self)
    end

noop() click to toggle source

(see noop?)

    # File lib/puppet/type.rb, line 1086
    def noop
      noop?
    end

noop?() click to toggle source

Returns the `noop` run mode status of this. @return [Boolean] true if running in noop mode.

    # File lib/puppet/type.rb, line 1073
    def noop?
      # If we're not a host_config, we're almost certainly part of
      # Settings, and we want to ignore 'noop'
      return false if catalog and ! catalog.host_config?

      if defined?(@noop)
        @noop
      else
        Puppet[:noop]
      end
    end

parameter(name) click to toggle source

Returns the value of this object’s parameter given by name @param name [String] the name of the parameter @return [Object] the value

    # File lib/puppet/type.rb, line 752
    def parameter(name)
      @parameters[name.to_sym]
    end

parameters() click to toggle source

Returns a shallow copy of this object’s hash of parameters. @todo Add that this is not only “parameters”, but also “properties” and “meta-parameters” ? Changes to the contained parameters will have an effect on the parameters of this type, but changes to the returned hash does not. @return [Hash{String => Puppet:???Parameter}] a new hash being a shallow copy of the parameters map name to parameter

    # File lib/puppet/type.rb, line 761
    def parameters
      @parameters.dup
    end

parent() click to toggle source

Returns the parent of this in the catalog. In case of an erroneous catalog where multiple parents have been produced, the first found (non deterministic) parent is returned. @return [???, nil] WHAT (which types can be the parent of a resource in a catalog?), or nil if there

    is no catalog.

    # File lib/puppet/type.rb, line 2293
    def parent
      return nil unless catalog

      unless defined?(@parent)
        if parents = catalog.adjacent(self, :direction => :in)
          # We should never have more than one parent, so let's just ignore
          # it if we happen to.
          @parent = parents.shift
        else
          @parent = nil
        end
      end
      @parent
    end

pathbuilder() click to toggle source

Creates the path for logging and such. @todo “and such?”, what? @api private

    # File lib/puppet/type.rb, line 1172
    def pathbuilder
      if p = parent
        [p.pathbuilder, self.ref].flatten
      else
        [self.ref]
      end
    end

properties() click to toggle source

@return [Array<Puppet::Property>] Returns all of the property objects, in the order specified in the

    class.

@todo “what does the ‘order specified in the class’ mean? The order the properties where added in the

    ruby file adding a new type with new properties?

    # File lib/puppet/type.rb, line 853
    def properties
      self.class.properties.collect { |prop| @parameters[prop.name] }.compact
    end

properties_to_audit(list) click to toggle source

    # File lib/puppet/type.rb, line 1259
    def properties_to_audit(list)
      if !list.kind_of?(Array) && list.to_sym == :all
        list = all_properties
      else
        list = Array(list).collect { |p| p.to_sym }
      end
    end

property(name) click to toggle source

Returns a {Puppet::Property} instance by name. To return the value, use ‘resource’ @todo LAK:NOTE(20081028) Since the ‘parameter’ method is now a superset of this method,

    this one should probably go away at some point. - Does this mean it should be deprecated ?

@return [Puppet::Property] the property with the given name, or nil if not a property or does not exist.

    # File lib/puppet/type.rb, line 777
    def property(name)
      (obj = @parameters[name.intern] and obj.is_a?(Puppet::Property)) ? obj : nil
    end

propertydefined?(name) click to toggle source

@return [Boolean] Returns whether the property given by name is defined or not. @todo what does it mean to be defined?

    # File lib/puppet/type.rb, line 767
    def propertydefined?(name)
      name = name.intern unless name.is_a? Symbol
      @parameters.include?(name)
    end

provider=(name) click to toggle source

Sets the provider to the given provider/name. @overload provider=(name)

    Sets the provider to the result of resolving the name to an instance of Provider.
    @param name [String] the name of the provider

@overload provider=(provider)

    Sets the provider to the given instances of Provider.
    @param provider [Puppet::Provider] the provider to set

@return [Puppet::Provider] the provider set @raise [ArgumentError] if the provider could not be found/resolved.

    # File lib/puppet/type.rb, line 1898
    def provider=(name)
      if name.is_a?(Puppet::Provider)
        @provider = name
        @provider.resource = self
      elsif klass = self.class.provider(name)
        @provider = klass.new(self)
      else
        raise ArgumentError, "Could not find #{name} provider of #{self.class.name}"
      end
    end

purging() click to toggle source

Marks the object as “being purged”. This method is used by transactions to forbid deletion when there are dependencies. @todo what does this mean; “mark that we are purging” (purging what from where). How to use/when?

    Is this internal API in transactions?

@see purging?

    # File lib/puppet/type.rb, line 2330
    def purging
      @purging = true
    end

purging?() click to toggle source

Returns whether this resource is being purged or not. This method is used by transactions to forbid deletion when there are dependencies. @return [Boolean] the current “purging” state

    # File lib/puppet/type.rb, line 2338
    def purging?
      if defined?(@purging)
        @purging
      else
        false
      end
    end

ref() click to toggle source

Returns a reference to this as a string in “Type” format. @return [String] a reference to this object on the form ‘Type’

    # File lib/puppet/type.rb, line 2311
    def ref
      # memoizing this is worthwhile ~ 3 percent of calls are the "first time
      # around" in an average run of Puppet. --daniel 2012-07-17
      @ref ||= "#{self.class.name.to_s.capitalize}[#{self.title}]"
    end

remove(rmdeps = true) click to toggle source

Removes this object (FROM WHERE?) @todo removes if from where? @overload remove(rmdeps)

    @deprecated Use remove()
    @param rmdeps [Boolean] intended to indicate that all subscriptions should also be removed, ignored.

@overload remove() @return [void]

    # File lib/puppet/type.rb, line 923
    def remove(rmdeps = true)
      # This is hackish (mmm, cut and paste), but it works for now, and it's
      # better than warnings.
      @parameters.each do |name, obj|
        obj.remove
      end
      @parameters.clear

      @parent = nil

      # Remove the reference to the provider.
      if self.provider
        @provider.clear
        @provider = nil
      end
    end

retrieve() click to toggle source

Retrieves the current value of all contained properties. Parameters and meta-parameters are not included in the result. @todo As oposed to all non contained properties? How is this different than any of the other

    methods that also "gets" properties/parameters/etc. ?

@return [Array<Object>] array of all property values (mix of types) @raise [fail???] if there is a provider and it is not suitable for the host this is evaluated for.

    # File lib/puppet/type.rb, line 1008
    def retrieve
      fail "Provider #{provider.class.name} is not functional on this host" if self.provider.is_a?(Puppet::Provider) and ! provider.class.suitable?

      result = Puppet::Resource.new(type, title)

      # Provide the name, so we know we'll always refer to a real thing
      result[:name] = self[:name] unless self[:name] == title

      if ensure_prop = property(:ensure) or (self.class.validattr?(:ensure) and ensure_prop = newattr(:ensure))
        result[:ensure] = ensure_state = ensure_prop.retrieve
      else
        ensure_state = nil
      end

      properties.each do |property|
        next if property.name == :ensure
        if ensure_state == :absent
          result[property] = :absent
        else
          result[property] = property.retrieve
        end
      end

      result
    end

retrieve_resource() click to toggle source

??? @todo what does this do? It seems to create a new Resource based on the result of calling retrieve

    and if that is a Hash, else this method produces nil.

@return [Puppet::Resource, nil] a new Resource, or nil, if this object did not produce a Hash as the

    result from #retrieve

    # File lib/puppet/type.rb, line 1040
    def retrieve_resource
      resource = retrieve
      resource = Resource.new(type, title, :parameters => resource) if resource.is_a? Hash
      resource
    end

self_refresh?() click to toggle source

(see ::self_refresh) @todo check that meaningful yardoc is produced - this method delegates to “self.class.self_refresh” @return [Boolean] - ??? returns true when … what?

    # File lib/puppet/type.rb, line 2321
    def self_refresh?
      self.class.self_refresh
    end

set_default(attr) click to toggle source

@todo comment says “For any parameters or properties that have defaults and have not yet been

    set, set them now.  This method can be handed a list of attributes,
    and if so it will only set defaults for those attributes."

@todo Needs a better explanation, and investigation about the claim an array can be passed (it is passed

    to self.class.attrclass to produce a class on which a check is made if it has a method class :default (does
    not seem to support an array...

@return [void]

    # File lib/puppet/type.rb, line 789
    def set_default(attr)
      return unless klass = self.class.attrclass(attr)
      return unless klass.method_defined?(:default)
      return if @parameters.include?(klass.name)

      return unless parameter = newattr(klass.name)

      if value = parameter.default and ! value.nil?
        parameter.value = value
      else
        @parameters.delete(parameter.name)
      end
    end

should(name) click to toggle source

@return [Object, nil] Returns the ‘should’ (wanted state) value for a specified property, or nil if the

    given attribute name is not a property (i.e. if it is a parameter, meta-parameter, or does not exist).

    # File lib/puppet/type.rb, line 710
    def should(name)
      name = name.intern
      (prop = @parameters[name] and prop.is_a?(Puppet::Property)) ? prop.should : nil
    end

suitable?() click to toggle source

@return [Boolean] Returns true if this is something else than a `:provider`, or if it

    is a provider and it is suitable, or if there is a default provider. Otherwise, false is returned.

    # File lib/puppet/type.rb, line 1870
    def suitable?
      # If we don't use providers, then we consider it suitable.
      return true unless self.class.paramclass(:provider)

      # We have a provider and it is suitable.
      return true if provider && provider.class.suitable?

      # We're using the default provider and there is one.
      if !provider and self.class.defaultprovider
        self.provider = self.class.defaultprovider.name
        return true
      end

      # We specified an unsuitable provider, or there isn't any suitable
      # provider.
      false
    end

tags=(list) click to toggle source

Sets the initial list of tags… @todo The initial list of tags, that … that what? @return [void] ???

    # File lib/puppet/type.rb, line 1998
    def tags=(list)
      tag(self.class.name)
      tag(*list)
    end

title() click to toggle source

Returns the title of this object, or it’s name if title was not explicetly set. If the title is not already set, it will be computed by looking up the {#name_var} and using that value as the title. @todo it is somewhat confusing that if the #name_var is a valid parameter, it is assumed to

    be the name_var called :name, but if it is a property, it uses the name_var.
    It is further confusing as Type in some respects supports multiple namevars.

@return [String] Returns the title of this object, or it’s name if title was not explicetly set. @raise [??? devfail] if title is not set, and #name_var can not be found.

    # File lib/puppet/type.rb, line 2355
    def title
      unless @title
        if self.class.validparameter?(name_var)
          @title = self[:name]
        elsif self.class.validproperty?(name_var)
          @title = self.should(name_var)
        else
          self.devfail "Could not find namevar #{name_var} for #{self.class.name}"
        end
      end

      @title
    end

to_hash() click to toggle source

@todo the comment says: “Convert our object to a hash. This just includes properties.” @todo this is confused, again it is the @parameters instance variable that is consulted, and

    each value is copied - does it contain "properties" and "parameters" or both? Does it contain
    meta-parameters?

@return [Hash{ ??? => ??? }] a hash of WHAT?. The hash is a shallow copy, any changes to the

    objects returned in this hash will be reflected in the original resource having these attributes.

    # File lib/puppet/type.rb, line 811
    def to_hash
      rethash = {}

      @parameters.each do |name, obj|
        rethash[name] = obj.value
      end

      rethash
    end

to_resource() click to toggle source

@todo What to resource? Which one of the resource forms is prroduced? returned here? @return [??? Resource] a resource that WHAT???

    # File lib/puppet/type.rb, line 2379
    def to_resource
      resource = self.retrieve_resource
      resource.tag(*self.tags)

      @parameters.each do |name, param|
        # Avoid adding each instance name twice
        next if param.class.isnamevar? and param.value == self.title

        # We've already got property values
        next if param.is_a?(Puppet::Property)
        resource[name] = param.value
      end

      resource
    end

to_s() click to toggle source

Produces a reference to this in reference format. @see ref

    # File lib/puppet/type.rb, line 2372
    def to_s
      self.ref
    end

type() click to toggle source

@return [String] the name of this object’s class @todo Would that be “file” for the “File” resource type? of “File” or something else?

    # File lib/puppet/type.rb, line 824
    def type
      self.class.name
    end

uniqueness_key() click to toggle source

Produces a uniqueness_key @todo Explain what a #uniqueness_key is @return [Object] an object that is a uniqueness_key for this object

    # File lib/puppet/type.rb, line 418
    def uniqueness_key
      self.class.key_attributes.sort_by { |attribute_name| attribute_name.to_s }.map{ |attribute_name| self[attribute_name] }
    end

value(name) click to toggle source

@todo Comment says “Return a specific value for an attribute.”, as opposed to what “An upspecific value”??? @todo is this the ‘is’ or the ‘should’ value? @todo why is the return restricted to things that respond to :value? (Only non structural basic data types

    supported?

@return [Object, nil] the value of the attribute having the given name, or nil if the given name is not

    an attribute, or the referenced attribute does not respond to `:value`.

    # File lib/puppet/type.rb, line 835
    def value(name)
      name = name.intern

      (obj = @parameters[name] and obj.respond_to?(:value)) ? obj.value : nil
    end

version() click to toggle source

@todo What is this used for? Needs a better explanation. @return [???] the version of the catalog or 0 if there is no catalog.

    # File lib/puppet/type.rb, line 843
    def version
      return 0 unless catalog
      catalog.version
    end

virtual?() click to toggle source

@return [Boolean] Returns whether the resource is virtual or not

    # File lib/puppet/type.rb, line 2396
    def virtual?;  !!@virtual;  end