DRY for Ruby loops

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

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

This means that the loops are for "Variables", not just "Enumerator".

the 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
+4
source share
3 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
+4
source

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

This is not clear from your code. If you want to define instance variables by writing the Ruby code inside String and then using eval: don't do this!

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]
+2
source

JS, Ruby:)

:

  • , .
  • else nil, , Ruby nil
  • nil, , .
  • : , , / .
  • : Ruby snake_case, find_logs

, , - :

def find_logs(obj)
  log_type = ["E", "T", "L", "Te", "Le"].detect do |type|
    obj[type] && obj[type]["pkg"]
  end

  "@#{log_type} = #{obj[log_type]['pkg']}," if log_type
end

, , , .

, , Ruby, , , . - ( , ):

class LogFormatter
  LOG_TYPES = ["E", "T", "L", "Te", "Le"]

  def initialize(obj:)
    @obj = obj
  end

  def format
    "@#{log_type} = #{pkg}," if log_type
  end

  private

  attr_reader :obj

  def pkg
    @pkg ||= obj[log_type]["pkg"]
  end

  def log_type
    @log_type ||= LOG_TYPES.detect { |type| obj[type] && obj[type]["pkg"] }
  end

end

, , , - , "" - .

+1
source

Source: https://habr.com/ru/post/1663824/


All Articles