如何优化Ruby方法

问题描述

我有一个红宝石方法

def get_status(creds)
  client = create_client(creds)
  status = client.account_status
  client.close_session
  status
end

通常,我通过tapyield_self优化这种代码,但是在这里找不到优化它的好方法。

我提出的唯一解决方案:

def get_status(creds)
  create_client(creds).yeild_self do |client|
    [client,client.account_status]
  end.yield_self do |client,status|
    client.close_session
    status
  end
end

但这并不比原始解决方案好吗?

解决方法

一个人可以写下以下内容。

Code:
Seq_List=open('test.trunc..txt','r')#uses tab files from uniprot copied into notepad 250 work
data = Seq_List.readlines()
N,P = [],[]
for line in data:
        values = [str(s) for s in line.split()]
        N.append(values[0])
        P.append(values[1])
N.remove('Entry')
P.remove('Sequence')
print(P)
Sequencedict = {} 
for key in N: 
for value in P: 
    Sequencedict[key] = value 
    #P.remove(value) 
    break  
print(Sequencedict)
print(Sequencedict.values())
def idr (P):
for i in P:
    x= i.replace('Q','e').replace('R','b').replace('S','e').replace('T','e').replace('Y','e')]
    #print(x)#gives the converted sequences
    #print(type(x))#output x is a list
    for g in x:
        v=g.count('h')
        #print(v)
        y=g.count('e')+g.count('a')+g.count('b')
        #print(y)
        z=len(i)
        #print(values)
        #print(y/z)
        if y/z>.10: #and v/z<.10: #e/tot>.60=sumo
            print(i)
            print(Sequencedict.keys())#reprint i and swap based of dict
            print(v)
            print(y)
            print(y/z)
            print('Disorder Promoting=Yes')
        #else:
            #print('Disorder Promoting=No')
        idr (P)


  Output:
  ['MSRTIVALILLGLAALA','MARFLVALALFGVVAMTAA','MARLFVAVALFGVVAFAAAEK']
  {'P0CU41': 'MSRTIVALILLGLAALA','P0CU39': 'MSRTIVALILLGLAALA','P0CU40': 'MSRTIVALILLGLAALA'}
  dict_values(['MSRTIVALILLGLAALA','MSRTIVALILLGLAALA','MSRTIVALILLGLAALA'])
  MSRTIVALILLGLAALA
  dict_keys(['P0CU41','P0CU39','P0CU40'])
  14
  3
  0.17647058823529413
  Disorder Promoting=Yes
  MARFLVALALFGVVAMTAA
  dict_keys(['P0CU41','P0CU40'])
  17
  2
  0.10526315789473684
  Disorder Promoting=Yes
  MARLFVAVALFGVVAFAAAEK
  dict_keys(['P0CU41','P0CU40'])
  18
  3
  0.14285714285714285
  Disorder Promoting=Yes
class Client
  def account_status
    "Overdrawn!"
  end
  def close_session
    puts "It's closed"
  end
end
def create_client(creds)
  Client.new
end    
def get_status(creds)
  begin
    client = create_client(creds)
    client.account_status
  ensure
    client.close_session if client
  end
end

在问题中我比第一更喜欢吗?不。

在问题中,我比第二更喜欢吗?是的!

我是否更喜欢@max的答案?不。


我知道可以使用类方法ObjectSpace::define_finalizer创建 finalizer

get_status("Anything")
It's closed
  #=> "Overdrawn!"
class Client
  def initialize
    ObjectSpace.define_finalizer(self,proc { puts "It's finalized!" })
  end

  def account_status
    "Overdrawn!"
  end
end
def create_client(creds)
  Client.new
end    
def get_status(creds)
  create_client(creds).account_status
end

创建终结器时必须小心,如Here所述。我了解有时使用的一种技术是拥有get_status("Anything") #=> "Overdrawn!" exit It's finalized! 的proc引用类级对象。例如,请参见this article,下面的@Amadan评论和对该问题的@Matt评论。我不主张使用终结器。我只是以为不熟悉终结器的读者(就像我在写这篇文章之前一样)会觉得这很有用。

,

让我们列出该功能的目标:

  1. 打开连接
  2. 读取值(并返回值)
  3. 关闭连接

我认为这是“临时连接”,这使我认为可以将其重构为单独的方法。

理由:get_status方法涉及从连接中获取状态-它不必处理实际关闭/打开连接本身的详细信息。

def open_temporary_connection(creds,&block)
  client = create_client(creds)
  result = block.call(client)
  client.close_session
  result
end

def get_status(creds)
  open_temporary_connection(creds,&:account_status)
end

我还要提到,我认为yield_self有点陷阱。除非您对将所有代码都变成一个单一表达式一无所知,否则它会使代码看起来很尴尬,而不会带来很多好处。

,

我喜欢您的第一个版本,因为它简短,易于阅读且易于理解。我不会改变它。

尽管如此,使用tap的替代版本可能看起来像这样:

def get_status(creds)
  client = create_client(creds)
  client.account_status.tap { client.close_session }
end

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...