question / help needed with conditionally passing variables to a module

i have a role that can optionally be provided a rbenv_gem_version variable that should then be optionally provided to the gem module in it’s tasks.

this seems very difficult to do with a large amount of copy-pasta due to modules differentiating between being passed null (Python None) and not being passed anything.

this is confusing because the Developing Modules docs state:

If required is false, you should document default, even if the default is ‘null’ (which is the default if no parameter is supplied). Make sure default parameter in docs matches default parameter in code.

the module is question is the gem module, and even though the optional version parameter does not have a specified default, i would infer from the above docs that it would default to null.

however, it seems like invoking

`

  • gem:
    name: lunchy
    `

is different than

`

  • gem:
    name: lunchy
    version: null
    `

the later resulting in a bad command:

`
/Users/nrser/.rbenv/versions/2.1.6/bin/gem install --version None --no-user-install --no-document lunchy"

`

the pertinent parts of my role are as follows:

in nrser.rbenv_gem/defaults/main.yml

rbenv_gem_version: null

in nrser.rbenv_gem/tasks/manage-version.yml

`

  • name: “manage {{ rbenv_gem_name }} gem in rbenv rubies”
    gem:
    name: “{{ rbenv_gem_name }}”
    user_install: “{{ rbenv_gem_user_install }}”
    state: “{{ rbenv_gem_state }}”
    version: “{{ rbenv_gem_version }}”
    executable: “{{ ansible_env.HOME }}/.rbenv/versions/{{ item }}/bin/gem”
    when: item != ‘system’
    with_items: “{{ rbenv_gem_rubies }}”

`

is there a way of fixing this besides this?

`

  • name: “manage {{ rbenv_gem_name }} gem in rbenv rubies”
    gem:
    name: “{{ rbenv_gem_name }}”
    user_install: “{{ rbenv_gem_user_install }}”
    state: “{{ rbenv_gem_state }}”
    executable: “{{ ansible_env.HOME }}/.rbenv/versions/{{ item }}/bin/gem”
    when: rbenv_gem_version and (item != ‘system’)
    with_items: “{{ rbenv_gem_rubies }}”

  • name: “manage {{ rbenv_gem_name }} gem in rbenv rubies”
    gem:
    name: “{{ rbenv_gem_name }}”
    user_install: “{{ rbenv_gem_user_install }}”
    state: “{{ rbenv_gem_state }}”
    version: “{{ rbenv_gem_version }}”
    executable: “{{ ansible_env.HOME }}/.rbenv/versions/{{ item }}/bin/gem”
    when: (not rbenv_gem_version) and (item != ‘system’)
    with_items: “{{ rbenv_gem_rubies }}”

`

besides being an annoying amount of copy-paste to maintain, this approach seems like it will spiral out of control with combinatoric complexity as a function of the number of optional variables in the module invocation.

thanks in advance,

Neil.

That is a documentation bug, the ‘default’ for version is actually ‘’ <= empty string.

so… is the empty string the default for all module params? or are you talking specifically about the version param in the gem module?

Only version, the default can be set at each module, null/None is only if that module parameter does not specify one (in args spec, docs in this case are out of sync).

where would i see that? i’m looking here and it doesn’t seem that any default is specified, just a type=‘str’ and required=False: https://github.com/ansible/ansible-modules-core/blob/devel/packaging/language/gem.py#L222