问题描述
我有一个红宝石方法
def get_status(creds)
client = create_client(creds)
status = client.account_status
client.close_session
status
end
通常,我通过tap
或yield_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评论。我不主张使用终结器。我只是以为不熟悉终结器的读者(就像我在写这篇文章之前一样)会觉得这很有用。
让我们列出该功能的目标:
- 打开连接
- 读取值(并返回值)
- 关闭连接
我认为这是“临时连接”,这使我认为可以将其重构为单独的方法。
理由: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