ruby 记忆多行法-导轨

czq61nw1  于 2023-03-12  发布在  Ruby
关注(0)|答案(5)|浏览(190)

在使用rails之前,我从未实现过记忆化,我认为我遇到了一个很好的使用案例,但我不知道如何去做。

方法:

def manager_rep_code_and_name
    manager = []

    rep_code_list.each do |rep_code|
      context = Finfolio::GetManagerByRepCode.call(rep_code: rep_code)

      manager.push({name: context.manager.response.first["Name"], rep_code: rep_code})
    end

    manager
  end

这个方法进行了一个网络调用,可能需要一段时间来解决这个问题。有没有办法我可以memoize这个方法,所以如果它已经存在,我不必出去,使这个请求再次。

类似这样:

def manager_rep_code_and_name
   @managers ||= manager = []

   rep_code_list.each do |rep_code|
     context = Finfolio::GetManagerByRepCode.call(rep_code: rep_code)

     manager.push({name: context.manager.response.first["Name"], rep_code: rep_code})
   end

  manager
end

显然,那不起作用,但我现在有点卡住了。

oaxa6hgo

oaxa6hgo1#

我经常把这样的方法分开:

def fetch_manager_rep_code_and_name
  rep_code_list.map do |rep_code|
    context = Finfolio::GetManagerByRepCode.call(rep_code: rep_code)
    { name: context.manager.response.first['Name'], rep_code: rep_code }
  end
end

def manager_rep_code_and_name
  @manager_rep_code_and_name ||= fetch_manager_rep_code_and_name
end

通常,这也使得它们更容易测试。

tf7tbtn2

tf7tbtn22#

您可以使用beginend块来存储多行代码的结果:

def manager_rep_code_and_name
   @manager_rep_code_and_name ||= begin
     manager = []

     rep_code_list.each do |rep_code|
       context = Finfolio::GetManagerByRepCode.call(rep_code: rep_code)

       manager.push({name: context.manager.response.first["Name"], rep_code: rep_code})
     end

    manager
  end
end
qyuhtwio

qyuhtwio3#

如果你想为同一个函数存储不同的输入/输出对,那么记忆就稍微复杂一些。因为这里没有输入,而且每次的输出都是相同的,所以记忆就非常简单了,就像这样:

def manager_rep_code_and_name
    return @manager if @manager
    @manager = []
    rep_code_list.each do |rep_code|
      context = Finfolio::GetManagerByRepCode.call(rep_code: rep_code)
      @manager.push({name: context.manager.response.first["Name"], rep_code: rep_code})
    end
    @manager
  end

在本例中,将记忆化的示例变量命名为方法名的下划线版本-@_manager_rep_code_and_name是一种常见的约定。

hrysbysz

hrysbysz4#

def manager_rep_code_and_name
    @managers ||= []
    if @managers.blank?
      @managers = rep_code_list.map do |rep_code|
        context = Finfolio::GetManagerByRepCode.call(rep_code: rep_code)
        {name: context.manager.response.first["Name"], rep_code: rep_code}
      end
    end
    @managers
  end

变量名从@manager命名为@managers,因为它包含一个数据列表。

ws51t4hk

ws51t4hk5#

您可以使用then,它将返回给定块的值。

def manager_rep_code_and_name
   @manager_rep_code_and_name ||= [].then do |managers|
     rep_code_list.each do |rep_code|
       context = Finfolio::GetManagerByRepCode.call(rep_code: rep_code)

       managers.push({name: context.manager.response.first["Name"], rep_code: rep_code})
    end
  end
end

相关问题