我有以下型号:
class User < ActiveRecord::Base
def send_message(content)
MessagePoro.new(content).deliver!
end
def self.send_to_all(content)
threads = []
all.each do |user|
threads << Thread.new do
user.send_message(content)
end
end
threads.each(&:join)
end
end
Run Code Online (Sandbox Code Playgroud)
MessagePoro模型可以很简单,例如app/models/message_poro.rb:
class MessagePoro
def initialize(content)
# ...
end
def deliver!
# ...
end
end
Run Code Online (Sandbox Code Playgroud)
现在,当我有100个用户,并且我正在运行User.send_to_all("test")时,我有时会遇到更严重的错误:
RuntimeError: Circular dependency detected while autoloading constant MessagePoro
Run Code Online (Sandbox Code Playgroud)
要么:
wrong number of arguments (1 for 0)
Run Code Online (Sandbox Code Playgroud)
我认为它必须是因为没有加载MessagePoro并且所有线程都试图同时加载它,或类似的东西.由于这些错误有时只会发生,我很确定只有当存在"竞争条件"或者有线程时才会出现这种情况.我已经尝试在启动Threads之前初始化MessagePoro,并且我已经使用了eager_loading,但问题似乎仍然存在.还有什么可以尝试缓解这个问题?
通常我在config/application.rb中添加以下内容来添加autload_paths:
config.autoload_paths += Dir[Rails.root.join('app', 'poros', '{**}')]
Run Code Online (Sandbox Code Playgroud)
如何在引擎中实现相同的目标?它似乎在我在主机应用程序中的application.rb中使用相同的代码时工作,但是我认为代码不在引擎中并且需要添加到主机应用程序以使事情有效是很难看的.
我发现通过引擎添加加载路径的唯一解决方案是将其添加到lib/engine/engine.rb:
config.to_prepare do
Dir.glob(Rails.root + "../../app/poros/**/*.rb").each do |c|
require_dependency(c)
end
end
Run Code Online (Sandbox Code Playgroud)
然而,这似乎有一些根本性的错误,因为这会在我进行控制台重新加载时导致问题(例如,它告诉我已经定义了常量或者关注点无法执行包含块两次)
在引擎本身中执行此操作的正确方法是什么?(不敢相信这是如此艰难/不常见,我真的google了很多,但我找不到解决方案)
我有一个大小约10 GB的字符串(大量的RAM使用...).问题是,我需要执行像gsub和split这样的字符串操作.我注意到Ruby会在某个时刻"停止工作"(尽管没有产生任何错误).
例:
str = HUGE_STRING_10_GB
# I will try to split the string using .split:
str.split("\r\n")
# but Ruby will instead just return an array with
# the full unsplitted string itself...
# let's break this down:
# each of those attempts doesn't cause problems and
# returns arrays with thousands or even millions of items (lines)
str[0..999].split("\r\n")
str[0..999_999].split("\r\n")
str[0..999_999_999].split("\r\n")
# starting from here, problems will occur
str[0..1_999_999_999].split("\r\n")
Run Code Online (Sandbox Code Playgroud)
我正在使用Ruby MRI 1.8.7,这里有什么问题?为什么Ruby无法对巨大的字符串执行字符串操作?什么是解决方案?
我想出的唯一解决方案是使用[0..9],[10..19],"循环"字符串,并逐个执行字符串操作.然而,这似乎是不可靠的,例如,如果我的拆分分隔符非常长并且落在两个"部分"之间.
实际上工作正常的另一个解决方案是像str.each_line {..}一样迭代字符串.但是,这只是替换了换行符分隔符.
编辑:谢谢你的所有答案.就我而言,"巨大的10 GB STRING"实际上是从互联网上下载的.它包含由特定序列分隔的数据(在大多数情况下是简单的换行符).在我的场景中,我将10 GB文件的EACH ELEMENT与我脚本中已有的另一个(较小的)数据集进行比较.我感谢所有的建议.
据我所知,Array类已经混合在Enumerable模块中.
如果是这样,为什么不存在[:example].next呢?
我为什么需要制作它[:example].to_enum.next?
我有字符串"V\355ctor"(我认为是Víctor).有没有办法将其转换为ASCII,í将被ASCII替换i?
我已经尝试过没有成功的Iconv.(我只是得到了Iconv::IllegalSequence: "\355ctor")
此外,Ruby 1.8.7和Ruby 2.0之间存在差异吗?
编辑:
Iconv.iconv('UTF-8//IGNORE', 'UTF-8', "V\355ctor")这似乎工作,但结果Vctor不是Victor