Search code examples
ruby-on-railsrubyslim-lang

Local variable ternary assignment in slim


I have a slim partial like so:

- name = (defined?(name) ? name : 'tags')
- id = (defined?(id) ? id : ('input-' + name))
- label = defined?(label) ? label : nil
- placeholder = defined?(placeholder) ? placeholder : nil
- className = defined?(className) ? className : nil
- prefetch = defined?(prefetch) ? prefetch : nil
- displayKey = defined?(displayKey) ? displayKey : nil
- valueKey = defined?(valueKey) ? valueKey : nil

.input-container.tags
  - if label
    label for="#{id}" = label
  input type="text" id="#{id}" name="#{name}" placeholder="#{placeholder}" data-prefetch="#{prefetch}" data-displayKey="#{displayKey}" data-valueKey="#{valueKey}"

When I use it (via ==render) and pass locals inside — everything is ok.

But when I omit, for example, name - it is not assigning to default 'tags'. And the same is for id. They are simply empty. If I comment out assignments in the beginning — undefined variable error raises, as expected.

What is wrong with assignments?


Solution

  • You don't need slim. Just irb the code:

    name = (defined?(name) ? name : 'tags')
    p name #=> nil
    

    It does not work, because you implicitly define name on the left side of the statement name = .... So when Ruby interpreter evaluates defined?(name) it gives truly result.

    I think you already get the answer:

    unless defined?(name)
      name = 'tags'
    end
    

    or shorter:

    name ||= 'tags'