【问题标题】:How can I execute a block to populate a variable only if the variable is blank?仅当变量为空时,如何执行块以填充变量?
【发布时间】:2013-10-18 17:31:30
【问题描述】:

我在一个类中有一些实例方法必须按顺序调用。序列中任何方法的失败都需要重新调用之前的方法。我将每个成功的方法调用的结果存储在一个类变量中:

class User
  @@auth_hash = {}
  def get_auth_token
    result = MyApi.get_new_auth_token(self) if @@auth_hash[self]['auth_token'].blank?
    if result['Errors']
      raise Exception, "You must reauthorize against the external application."
    else
      @@auth_hash[self]['auth_token'] = result['auth_token']
    end
    @@auth_hash[self]['auth_token']
  end
  def get_session_id
    result = MyApi.get_new_session_id if @@auth_hash[self]['session_id'].blank?
    if result['Errors']
      get_auth_token
      # Recursion
      get_session_id
    else
      @@auth_hash[self]['session_id'] = result['session_id']
    end
    @@auth_hash[self]['session_id']
  end
end

我想摆脱这些条件,但不知道如何仅在返回的哈希中存在错误时执行块。

【问题讨论】:

  • 看起来get_session_id 的第一行如果满足你的条件就会产生无限递归——实际上是这样写的吗?
  • 我只是拼凑这些来模拟我真正拥有的东西,但是如果 result['Errors'] 为 nil,则条件将不会执行。
  • @@auth_hash 到底是什么?使用类变量通常表明您的设计有问题。您是否在这里将其用作某种缓存?这通常会适得其反,缓存只适用于一个进程,其中通常有很多,而且你这里没有失效代码。
  • @AKWF 你考虑过 Zach Kemp 的评论吗?这种无限递归似乎没用。
  • result => nilif @@auth_hash[self]['session_id'].blank? => false。你想要那个吗?如果没有,请解决这个问题,我们也许可以提供帮助。

标签: ruby conditional idioms


【解决方案1】:

整个方法需要重写...但是要回答您的问题,为什么以下方法不起作用?

my_proc = ->(){ fill_me_with_something }
my_var ||= my_proc.call

raise StandardError if my_var.nil?

编辑我的答案以更好地回答问题...语法:

 my_proc  =   ->(a,b){ a + b } 

是另一种表达块的方式,用于所有意图和目的:

 my_proc(1, 5)   #=> 6

你也可以用这种格式表达 Procs:

 my_proc = Proc.new{ |a, b| a + b }

使用 Proc 的优点是您可以将类似块的行为设置为某个变量,然后在需要时在该 proc 上调用 call,在您的情况下,当某个其他变量为空时。

【讨论】:

  • 谢谢丹!第一行有一些我不认识的东西:如果你必须用英语写第一行,你会怎么说?我理解分配和块,但“->()”对我来说是个谜。
  • 这是 Proc 的简写...所以另一种写法是:my_proc = Proc.new{|val| puts val}(呃,搞砸了,只是要编辑我的答案)
  • 我喜欢这个。我从来不知道这个速记,非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-27
  • 2020-01-31
  • 2022-01-10
  • 1970-01-01
相关资源
最近更新 更多