Ruby 2.4在Rails 5.1中的可枚举#个和

时间:2017-12-26 17:59:22

标签: ruby ruby-on-rails-5.1

在使用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项目中,我没有收到此错误。这里发生了什么?

2 个答案:

答案 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/c‌​ore_ext/enumerable.r‌​b并查看自定义[].method(:sum).super_method.source_location是否是罪魁祸首。