Do Ruby objects have a size limit?
There is a limit. A String
can be 2**31 - 1
(and accordingly 2**63 - 1
on 64 bit ruby). You can see the limit with:
>> s = String.new("1" * (2**32))
RangeError: bignum too big to convert into `long'
from (irb):3:in `*'
from (irb):3
>> s = String.new("1" * (2**31))
RangeError: bignum too big to convert into `long'
from (irb):4:in `*'
from (irb):4
Having said that, while you could try to allocate a string that big it will likely fail (at least on a 32 bit system as typically the maximum amount of memory a process can allocate is between 2.5 and 3GB and a 2**31 - 1
length string is nearly 2GB by itself.) As seen:>> "1" * (2**30)
NoMemoryError: failed to allocate memory
from /usr/lib/ruby/1.8/irb.rb:310:in `inspect'
from /usr/lib/ruby/1.8/irb.rb:310:in `output_value'
from /usr/lib/ruby/1.8/irb.rb:159:in `eval_input'
from /usr/lib/ruby/1.8/irb.rb:271:in `signal_status'
from /usr/lib/ruby/1.8/irb.rb:155:in `eval_input'
from /usr/lib/ruby/1.8/irb/ruby-lex.rb:244:in `each_top_level_statement'
from /usr/lib/ruby/1.8/irb/ruby-lex.rb:230:in `loop'
from /usr/lib/ruby/1.8/irb/ruby-lex.rb:230:in `each_top_level_statement'
from /usr/lib/ruby/1.8/irb/ruby-lex.rb:229:in `catch'
from /usr/lib/ruby/1.8/irb/ruby-lex.rb:229:in `each_top_level_statement'
from /usr/lib/ruby/1.8/irb.rb:154:in `eval_input'
from /usr/lib/ruby/1.8/irb.rb:71:in `start'
from /usr/lib/ruby/1.8/irb.rb:70:in `catch'
from /usr/lib/ruby/1.8/irb.rb:70:in `start'
from /usr/bin/irb:13
Maybe IRB bug!!
I don't believe there is any way to catch the NoMemoryError
.Updated to reflect the comment from sepp2k
Ruby/Rails - Limit the size of a object/hash
First of all, if you'd like to have pagination, I strongly suggest taking a look at will_paginate
Alternatively, you can do the following to read the first 10 records only.
<% @events.first(10).each do |event| %>
<p><%= event.name %></p>
<% end %>
Or the last 10 records<% @events.last(10).each do |event| %>
<p><%= event.name %></p>
<% end %>
I didn't test it but you get the point. Is there a limit on the size of an array in ruby?
There is not a software limit imposed by Ruby, but there is a limit as to how much the process can support. If you have a regular home server running the Ruby server, it would be able to handle an array until the array became too large, at which point it would begin to 'bog down', lag, crash, etc. On the other hand, if you had an extremely powerful corporate server, it could handle a much larger array, but would still eventually crash/lag if the array became too large for the process and the hardware (memory) to handle.
I don't have any concrete numbers for you, because it all depends on the hardware and software on the server.
Is there a size limit on data stored in the flash[] object?
They are stored in the session, just like using session[:big_data]
.
Session has a limit of 4K, however, you can change your session store in config/initializers/session_store.rb
Here is an example of an alternate session store https://github.com/roidrage/redis-session-store
Rails 3.1 limit user created objects
Try something like this:
class User < ActiveRecord::Base
has_many :things
end
class Things <ActiveRecord::Base
belongs_to :user
validate :thing_count_within_limit, :on => :create
def thing_count_within_limit
if self.user.things(:reload).count >= 5
errors.add(:base, "Exceeded thing limit")
end
end
end
Edit: updated for Rails 3 Working with a large data object between ruby processes
A sinatra app will work, but the {un}serializing, and the HTML parsing could impact performance compared to a DRb service.
Here's an example, based on your example in the related question. I'm using a hash instead of an array so you can use user ids as indexes. This way there is no need to keep both a table on interests and a table of user ids on the server. Note that the interest table is "transposed" compared to your example, which is the way you want it anyways, so it can be updated in one call.
# server.rb
require 'drb'
class InterestServer < Hash
include DRbUndumped # don't send the data over!
def closest(cur_user_id)
cur_interests = fetch(cur_user_id)
selected_interests = cur_interests.each_index.select{|i| cur_interests[i]}
scores = map do |user_id, interests|
nb_match = selected_interests.count{|i| interests[i] }
[nb_match, user_id]
end
scores.sort!
end
end
DRb.start_service nil, InterestServer.new
puts DRb.uri
DRb.thread.join
# client.rb
uri = ARGV.shift
require 'drb'
DRb.start_service
interest_server = DRbObject.new nil, uri
USERS_COUNT = 10_000
INTERESTS_COUNT = 500
# Mock users
users = Array.new(USERS_COUNT) { {:id => rand(100000)+100000} }
# Initial send over user interests
users.each do |user|
interest_server[user[:id]] = Array.new(INTERESTS_COUNT) { rand(10) == 0 }
end
# query at will
puts interest_server.closest(users.first[:id]).inspect
# update, say there's a new user:
new_user = {:id => 42}
users << new_user
# This guy is interested in everything!
interest_server[new_user[:id]] = Array.new(INTERESTS_COUNT) { true }
puts interest_server.closest(users.first[:id])[-2,2].inspect
# Will output our first user and this new user which both match perfectly
To run in terminal, start the server and give the output as the argument to the client:$ ruby server.rb
druby://mal.lan:51630
$ ruby client.rb druby://mal.lan:51630
[[0, 100035], ...]
[[45, 42], [45, 178902]]
In Ruby, can I limit the amount of drilling down a object does when displaying itself in irb or when using .inspect?
Redefine inspect in Puzzle and display only what you want.
For example:
def inspect
"Puzzle with size #{rows.size}"
end
How to limit the number of items that can be added to an ActiveRecord array
You can use a before_add callback (scroll down to heading "Association callbacks") on your association to enforce the behavior
Should any of the before_add callbacks throw an exception, the object does not get added to the collection. Same with the before_remove callbacks; if an exception is thrown the object doesn’t get removed.
Arrays in Ruby: Take vs Limit vs First
- limit is not an array method
- take requires an argument; it returns an empty array if the array is empty.
- first can be called without an argument; it returns nil if the array is empty and the argument is absent.
static VALUE
rb_ary_take(VALUE obj, VALUE n)
{
long len = NUM2LONG(n);
if (len < 0) {
rb_raise(rb_eArgError, "attempt to take negative size");
}
return rb_ary_subseq(obj, 0, len);
}
Source for 2.0 first: static VALUE
rb_ary_first(int argc, VALUE *argv, VALUE ary)
{
if (argc == 0) {
if (RARRAY_LEN(ary) == 0) return Qnil;
return RARRAY_PTR(ary)[0];
}
else {
return ary_take_first_or_last(argc, argv, ary, ARY_TAKE_FIRST);
}
}
In terms of Rails:
limit(5)
will add the scope oflimit(5)
to anActiveRecord::Relation
. It can not be called on an array, solimit(5).limit(4)
will fail.first(5)
will add the scope oflimit(5)
to anActiveRecord::Relation
. It can also be called on an array so.first(4).first(3)
will be the same as.limit(4).first(3)
.take(5)
will run the query in the current scope, build all the objects and return the first 5. It only works on arrays, soModel.take(5)
will not work, though the other two will work.
Related Topics
How to Use Strong Parameters with an Objects Array in Rails
Use Pry in Gems Without Modifying The Gemfile or Using 'Require'
What Is The Ruby Equivalent to This Curl Request
Pg.Rb Segmentation Fault [Mojave Upgrade]
Typeerror: Can't Convert Net::Httpok into String
How to Downgrade My Rails Version
Fresh Ruby Gem from Bundler - Cannot Load My Version.Rb File
How to Add Usr/Local/Bin to Path Environment Variable on Ubuntu 12.0.4
How to Access HTML Request Parameters for a .Rhtml Page Served by Webrick
How to Host Gem in Github and Use It
How to Convert a Fraction to Float in Ruby
Ruby Gem Development - How to Use Activerecord
Automating Ssh to Windows with Ruby
How to Add Values Dynamically to I18N
Mongodb Server Doesn't Start at Gitlab Runner Using Gitlab-Ci