在使用Ruby 2.3.5的Rails 5.1.4中,我得到了这种行为:
>> [].sum
#> nil
我想升级到Ruby 2.4,其中Enumerable#sum是本机实现的。使用Ruby 2.4.2在IRB中测试这个,我得到了这个结果:
>> [].sum
#> 0
没关系,我可以处理不同的结果。但是使用Ruby 2.4.2回到Rails 5.1.4中的Rails控制台,我得到了这个:
>> [].sum
#> NoMethodError: undefined method `each' for nil:NilClass
但是,在新创建的Rails 5.1.4项目中,我没有收到此错误。这里发生了什么?
答案 0 :(得分:1)
我认为您的应用程序在sum方法上有一些过度隐藏。使用2个不同版本的ruby
查看下面的示例,其中包含2个新应用程序/testapp# ruby --version
ruby 2.4.2p198 (2017-09-14 revision 59899) [x86_64-linux]
/testapp# rails --version
Rails 5.1.4
/testapp# rails c
irb(main):001:0> [].sum
=> 0
和另一个版本
/testapp# ruby --version
ruby 2.3.5p376 (2017-09-14 revision 59905) [x86_64-linux]
/testapp# rails --version
Rails 5.1.4
/testapp# rails c
irb(main):001:0> [].sum
=> 0
答案 1 :(得分:1)
看看source for the Active Support enumerable extensions看起来似乎有点奇怪,因为你不应该使用Ruby 2.3.5获得你为Rails 5.1.4描述的行为,即你应该得到的0也不是def processText(lines, selected_date, word="DOWN"):
total = 0
start = None
print(selected_date)
# if there is `selected_date` then convert to `datetime`
if selected_date:
try:
selected_date = datetime.datetime.strptime(selected_date, "%d.%m.%Y")
except AttributeError as ex:
print("ERROR:", ex)
selected_date = None
# calculate time
for direction, t1, t2, seconds in lines:
if not word or word == direction:
# if `selected_date` then filter times
if selected_date and t1 <= selected_date:
continue
if not start:
start = t1.strftime("%d.%m.%Y %H:%M:%S")
total += seconds
# convert to minutes after summing all second
total = total//60
return total, start
def calculate():
all_dates = entry.get().split(',')
print(all_dates)
all_dates = [date.strip() for date in all_dates]
# calculate total number of minutes when it was down and up
total_down, start = processText(data, None, None)
print('total_down:', total_down)
txt = ''
for current_date in all_dates:
down, start = processText(data, current_date, "DOWN")
percentage = (down/total_down) * 100
txt += "Total Downtime is {} min from {} ({:.2f}%)\n".format(down, start, percentage)
textVar.set(txt)
。
有效支持nil
检查Array#sum
是否可以使用Ruby自己的sum
。对于空数组,这将为false,因此对first.is_a?(Numeric)
的调用将调用super
,而both implementations of that的默认值为0.
在现有项目的Rails控制台中尝试Enumerable#sum
,看看[].method(:sum).source_location
是否在某处被覆盖。
如果返回Array#sum
的预期行,则下一步将检查active_support/core_ext/enumerable.rb
并查看自定义[].method(:sum).super_method.source_location
是否是罪魁祸首。