skip to Main Content

I’m generating some local variables in a method. I would like to find a way of returning them in a hash with keys and values, but the generation of that very hash ends up in the return itself. How can I avoid this?

def get_map_libs()
  libjq = JSON.parse(File.read(URI.open('https://api.cdnjs.com/libraries/jquery', 'r')))['latest']
  liblf = JSON.parse(File.read(URI.open('https://api.cdnjs.com/libraries/leaflet', 'r')))['latest']
  libbs = JSON.parse(File.read(URI.open('https://api.cdnjs.com/libraries/twitter-bootstrap', 'r')))['latest']
  libfa = JSON.parse(File.read(URI.open('https://api.cdnjs.com/libraries/font-awesome', 'r')))['latest']
  return {libjq: libjq, liblf: liblf, libbs: libbs, libfa: libfa}
#   return local_variables
end

This method works as expected. There should be a way of grabbing local_variables and returning it. However, when I use that commented-out return (return local_variables), it only returns their keys:

[
    [0] :libjq,
    [1] :liblf,
    [2] :libbs,
    [3] :libfa
]

I tried building a return hash r = {} and populating it, however that very hash also shows up in the return. I tried deleting it, but that throws an error when I try to delete itself in itself.

Can this be done or do I have to hard code it like above?

2

Answers


  1. The documentation of local_variables tells that it only returns an array with the names of the local variables.

    But you could use that method to generate the hash:

    local_variables.map { |name| [name, eval(name.to_s)] }.to_h
    

    I think that is a bit error-prone because you might return unexpected variables and their values.

    Perhaps it would be better to refector your method to something like this:

    LIBRARIES = { 
      libjq: 'jquery',
      liblf: 'leaflet',
      libbs: 'twitter-bootstrap',
      libfa: 'font-awesome'
    }
    
    def library_urls
      LIBRARIES.map { |k, v| 
        [k, JSON.parse(URI.open("https://api.cdnjs.com/libraries/#{v}").read)['latest']] 
      }.to_h  
    end
    
    Login or Signup to reply.
  2. Well, the problem is that you are assigning the result hash to a local variable, so if you want to return a list of local variables, then of course that variable will be included.

    The two simplest solutions I can think of would be:

    Filter out the name of that local variable.

    Just don’t assign it. I.e. where you have r = something, just return something without assigning it to r in the first place. Something like this:

    def get_map_libs
      libjq = :jq
      liblf = :lf
      libbs = :bs
      libfa = :fa
    
      local_variables.map {|var| [var, binding.local_variable_get(var)] }.to_h
    end
    
    get_map_libs
    #=> { :libjq => :jq, :liblf => :lf, :libbs => :bs, :libfa => :fa }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search