Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DRY for Ruby variable loops

Tags:

ruby

I have a def in ruby like below. Can I do something to make it DRY? like:

[e,t,l,te,le,le].each |xxx| do
  if xxx
end

Which means do the loops for "Variables", not only "Enumerator".

code:

def findLogs (obj)
  if e=obj['E']
    e=obj['E']['pkg'] ? "@E = #{obj['E']['pkg']},":nil
  else nil
  end
  if t=obj['T']
    t=obj['T']['pkg'] ? "@T = #{obj['T']['pkg']},":nil
  else nil
  end
  if l=obj['L']
    l=obj['L']['pkg'] ? "@L = #{obj['L']['pkg']},":nil
  else nil
  end
  if te=obj['Te']
    te=obj['Te']['pkg'] ? "@Te = #{obj['Te']['pkg']},":nil
  else nil
  end
  if le=obj['Le']
    le=obj['Le']['pkg'] ? "@Le = #{obj['Le']['pkg']},":nil
  else nil
  end
end
like image 997
L_G Avatar asked Mar 10 '23 09:03

L_G


2 Answers

e, t, l, te, le = %w|E T L Te Le|.map do |s|
  obj[s] && obj[s]['pkg'] ? "@#{s} = #{obj[s]['pkg']}," : nil
end

For Sergio Tulentsev:

b = binding
%w|E T L Te Le|.each do |s|
  b.local_variable_set(
    s.downcase.to_sym,
    obj[s] && obj[s]['pkg'] ? "@#{s} = #{obj[s]['pkg']}," : nil
  )
end
like image 145
Aleksei Matiushkin Avatar answered Mar 17 '23 16:03

Aleksei Matiushkin


As Stefan mentioned in a comment, defining local variables in findLogs is pointless if you don't use them. Even if you define them twice ;).

It's not clear from your code. If you want to define instance variables by writing Ruby code inside a String, and using eval afterwards : please don't!

obj = {
  'E'  => nil,
  'T'  => { 'pkg' => 't_pkg' },
  'L'  => { 'not_pkg' => 'x' },
  'Te' => { 'pkg' => 'te_pkg' }
}

%w(E T L Te Le).each do |var_name|
  instance_variable_set("@#{var_name}", obj.dig(var_name, 'pkg'))
end

p [@E, @T, @L, @Te, @Le] # => [nil, "t_pkg", nil, "te_pkg", nil]
like image 34
Eric Duminil Avatar answered Mar 17 '23 15:03

Eric Duminil