Uploaded image for project: 'Puppet'
  1. Puppet
  2. PUP-4178

defined() function returns true for undef and empty string, and false for "main"



    • Bug
    • Status: Closed
    • Minor
    • Resolution: Done
    • None
    • PUP 3.8.1, PUP 4.1.0
    • None
    • None
    • Bug Fix


      The defined() function is written using the 3.x API and cannot differentiate between undefined and the empty string. Moving the function to the 4.x function API solves that issue.

      The second issue is if the main class (known as '' internally) really should be available under that name. Everyone knows it as "main", and it is not possible to create your own "main" class without causing strange side effects.

      puppet apply -e 'notice(defined(""))'
      Notice: Scope(Class[main]): true
      puppet apply -e 'notice(defined("main"))'
      Notice: Scope(Class[main]): false
      puppet apply -e 'notice(defined(undef))'
      Notice: Scope(Class[main]): true

      Further, it is not possible to ask specifically if a class foo is defined, or if a resource type foo is defined using the current version of the function since
      a request for Class[foo] requires that the class is included in the catalog, and a request for 'foo' is satisfied by either a built in type, a define
      or a class. For a resource type (built in or user defined) it is possible to ask for only the type e.g. File, or Resource[File]. To facilitate this, and for completeness, it should be possible to ask if Type[Class[foo]] is defined (as well as Type[Resource[T]] (even if the later is not absolutely required).

      The solutions (in PR 3840) produces:

      notice defined('')     # false
      notice defined(undef)  # error
      notice defined('main') # true
      class not_included { }
      notice defined('not_included') # true (but you don't know what it is)
      notice defined(Class[not_included]) # false
      notice defined(Type[Class[not_included]]) # true
      notice defined(Type[Class[non_existing]]) # false

      When defined is used with the future parser on 3.x, and always on 4.x

      risk: medium
      probability: medium
      severity: medium (confusing, can cause code to be unpredictable, but work arounds exist)
      test layer: unit


        Issue Links



              Unassigned Unassigned
              henrik.lindberg Henrik Lindberg
              0 Vote for this issue
              3 Start watching this issue



                Zendesk Support