What is Hash#count? - ruby

I was playing with IRB (Ruby 2.5.1) when I noticed this:
irb(main):020:0> h
=> {3=>4, :aaa=>false}
irb(main):021:0> h.count
=> 2
However, this method doesn't exist in Ruby docs.
A quick test shows that hsh.count gives the same result as hsh.keys.count, and Hash.ancestors contains Enumerable.
What exactly is Hash#count?

You seem to have gotten most of the way there... it's Enumerable#count.
Technically, hsh.keys.count is counting the keys, and hsh.count is counting the pairs (as would be yielded by hsh.each), but those are identical values in practice, because each pair has a unique key.

Related

Is the frozen behavior on Fixnum a specified behavior?

Here was the behavior that somewhat surprised me:
1.9.3-p392 :001 > n = 1
=> 1
1.9.3-p392 :002 > n.frozen?
=> false
1.9.3-p392 :003 > 1.freeze
=> 1
1.9.3-p392 :004 > n.frozen?
=> true
I tried grepping through the RubySpec source code for frozen and I didn't see anything about Fixnums at all.
Is this behavior the same as what would be expected on non-MRI Ruby implementations? If I run n = 1; 1.freeze; n.frozen?, will the final result always be true on any Ruby implementation? Why or why not?
It looks like it is an intended feature. In Ruby Forum, a question is raised:
Isn't technically all Fixnums "frozen" (because you can't modify the state)?
to which matz answers:
Not really, since fixnums could have instance variables.
Thus, theoretically, there's room for freezing fixnums. I don't think it's worth the cost though.
There seems to have been unintended inconsistency between different MRI Ruby versions, but as far as MRI is concerned, they look like they were identified as bugs, and were fixed. The specification you observed seems to be the intended one.
Since everything in Ruby is an object, it perhaps shouldn't be surprising that you can freeze 1. Symbol has the same behavior. As mentioned in the comments, this behavior changed from 1.8.7 (freezing didn't do anything) to 1.9+ (freezing works).
What might be more surprising is that freezing 1 also freezes n. According to the documentation for Fixnum,
There is effectively only one Fixnum object instance for any given
integer value
This means that n and 1 are references to the same object, and modifying one will modify the other.
You can check this for yourself by looking at the object_id.
1.object_id
=> 3
n=1
n.object_id
=> 3
n.equal? 1
=> true
I tried this code in MRI 1.8.7, MRI 2.0.0, JRuby, and Rubinius and got the same result.

Access Ruby hash variables

I am pretty new to ruby and sinatra but basically I have this route:
put '/user_list/:user_id' do
puts request.params["model"]
end
and it returns the following
{"password":"36494092d7d5682666ac04f62d624141","username":"nicholas","user_id":106,"firstname":"Nicholas","email":"nicholas#macpractice.com","is_admin":0,"lastname":"Rose","privileges":""}
I am now having a hard time accessing values of each of those. It doesn't really seem to be in hash format so I can't really do
request.params["model"][:password]
It just returns nil..
I just need to know what I can do to access those variables, or how to configure my request parameters to be in a good format to access variables.
Try request.params["model"]["password"]
A Hash's keys can consist of both symbols and strings. However, a string key is different than a symbol key.
Note the following:
h = {:name => 'Charles', "name" => 'Something else'}
h[:name] #=> 'Charles'
h["name"] #=> 'Something else'
EDIT:
In your particular situation, it appears request.params["model"] returns a string instead of a hash. There is a method String#[] which is a means of getting a substring.
s = "Winter is coming"
s["Winter"] #=> "Winter"
s["Summer"] #=> nil
This would explain your comments.
There are a couple things you can do to remedy your specific situation. I have found the most simplest way to be using JSON. (I'm sure there are others and maybe those will surface through other answers or through comments.)
require 'json'
hash_of_params = JSON.load(request.params["model"]).to_hash
hash_of_params["password"] #=> "36494092d7d5682666ac04f62d624141"
The standard Hash treats strings and symbols differently, and I'd be willing to bet that's what's happening in this case.
Use request.params["model"]["password"] to get the password.
The exception to that is when working with a HashWithIndifferentAccess which is part of ActiveSupport. For hashes of that type, either strings or symbols can be used to access the same elements.
Try the below,it will work too:
request.params["model"][:password.to_s]

Accessing objects memory address in ruby..?

Is there any way in Ruby to get the memory address of objects?
(i = 5)
Is it possible to get the memory address of that object 5?
I have been trying to get this over some time.
Yes.
From "Fiddling with Ruby’s Fiddle":
"You can get the actual pointer value of an object by taking the object id, and doing a bitwise shift to the left. This will give you the pointer (or memory location) of the ruby object in memory."
Using your example of i = 5 it could be done like so:
i = 5
i_ptr_int = i.object_id << 1
=> 22
"In Ruby, why does inspect() print out some kind of object id which is different from what object_id() gives?" has more info about object_id, including a brief introduction to the C source underlying the implementation which you might find helpful.
Take a look at "Fiddle" for some other cool things you can do.
Ruby Memory Validator should be able to pull that off but it's not free.
Aman Gupta patched Joe Damatos memprof but it seems to be a work in progress and I never got it to run on my machine. Joe has a couple of really good posts about memprof and other low level stuff on his blog.
Now I'm not so sure they really can. Integers are stored as a Fixnum and Fixnum is not a usual Ruby object, it just looks that way. Ruby uses a clever speed up trick with the object_id to make Fixnum objects immidiate values. The number is in fact stored in the object_id itself. That's why two different Fixnum containing the same value has the same object_id.
>> x=5
=> 5
>> y=5
=> 5
>> x.object_id
=> 11
>> y.object_id
=> 11
>> z=4711
=> 4711
>> z.object_id
=> 9423
The object_id of a Fixnum is actually created by bit shifting to the left and then setting the least significant bit.
5 is 0b101 and the object_id for 5 is 11 and 11 in binary is 0b1011.
4711 is 0b0001001001100111, shift left and set the bit and you get 0b0010010011001111 and that is 9423 which happens to be the object_id for z above.
This behaviour is most probably implementation specific but I don't know of a Ruby implementation that doesn't handle Fixnum this way.
There are at least three more immediate objects in Ruby and that's false, true and nil.
>> false.object_id
=> 0
>> true.object_id
=> 2
>> nil.object_id
=> 4
I don't know of a way of having the exact address, but maybe you're looking for something like the object_id method?
Extract from its documentation
Returns an integer identifier for obj.
The same number will be returned on all calls to id for a given object, and no two active objects will share an id
Example:
> 5.object_id
=> 11
> true.object_id
=> 2
Ruby Memory Validator does give you the memory address for the object.
Joe Damato's work (http://timetobleed.com/plugging-ruby-memory-leaks-heapstack-dump-patches-to-help-take-out-the-trash) and (http://timetobleed.com/memprof-a-ruby-level-memory-profiler) is based on the work Software Verification did to create a Ruby memory inspection API (http://www.softwareverify.com/ruby/customBuild/index.html).
Joe describes that on his blog. Therefore Joe's work should also return the appropriate addresses. I'm not fully up to speed with the latest version of Joe's work - he only told me about the first version, not the latest version, but nonetheless, if you are tracking memory allocations in the underpinnings of Ruby, you are tracking the addresses of the objects that hold whatever it is you are allocating.
That doesn't mean you can dereference the address and read the data value you expect to find at that address. Dereferencing the address will point you to the internals of a basic Ruby Object. Ruby objects are a basic object which then store additional data alongside, so knowing the actual address is not very useful unless you are writing a tool like Ruby Memory Validator or memprof.
How do I know the above about Ruby Memory Validator and the API we released? I designed Ruby Memory Validator. I also wrote the assembly language bits that intercept the Ruby calls that allocate the memory.
What exactly are you trying to do?
Keep in mind that a Ruby object is not directly analogous to a variable in a language like C or C++. For example:
a = "foo"
b = a
b[2] = 'b'
b
=> "fob"
a
=> "fob"
a == b
=> true
a.object_id
=> 23924940
b.object_id
=> 23924940
a.object_id == b.object_id
=> true
Even through a and b are separate variables, they are references to the same underlying data and have the same object_id.
If you find yourself needing to take the address of a variable, there is probably an easier approach to whatever you are trying to do.
Since you indicated (buried in a comment somewhere) that you're really just trying to understand how Ruby references things, I think things work as follows:
A VALUE in Ruby's C api represents an object (a nil, a FixNum or a Boolean) or a pointer to an Object. The VALUE contains a 3 bit tag indicating which of these it is, and contains the value (for the first 3) or a direct memory pointer (for an Object). There's no way to get at the VALUE directly in Ruby, (I'm not sure if the object_id is the same or different.)
Note that JRuby operates differently.

Why don't more projects use Ruby Symbols instead of Strings?

When I first started reading about and learning ruby, I read something about the power of ruby symbols over strings: symbols are stored in memory only once, while strings are stored in memory once per string, even if they are the same.
For instance: Rails' params Hash in the Controller has a bunch of keys as symbols:
params[:id] or
params[:title]...
But other decently sized projects such as Sinatra and Jekyll don't do that:
Jekyll:
post.data["title"] or
post.data["tags"]...
Sinatra:
params["id"] or
params["title"]...
This makes reading new code a little tricky, and makes it hard to transfer code around and to figure out why using symbols isn't working. There are many more examples of this and it's kind of confusing. Should we or shouldn't we be using symbols in this case? What are the advantages of symbols and should we be using them here?
In ruby, after creating the AST, each symbol is represented as a unique integer. Having symbols as hash keys makes the computing a lot faster, as the main operation is comparison.
Symbols are not garbage collected AFAIK, so that might be a thing to watch out for, but except for that they really are great as hash keys.
One reason for the usage of strings may be the usage of yaml to define the values.
require 'yaml'
data = YAML.load(<<-data
one:
title: one
tag: 1
two:
title: two
tag: 2
data
) #-> {"one"=>{"title"=>"one", "tag"=>1}, "two"=>{"title"=>"two", "tag"=>2}}
You may use yaml to define symbol-keys:
require 'yaml'
data = YAML.load(<<-data
:one:
:title: one
:tag: 1
:two:
:title: two
:tag: 2
data
) #-> {:one=>{:title=>"one", :tag=>1}, :two=>{:title=>"two", :tag=>2}}
But in the yaml-definition symbols look a bit strange, strings looks more natural.
Another reason for strings as keys: Depending on the use case, it can be reasonable to sort by keys, but you can't sort symbols (at least not without a conversion to strings).
The main difference is that multiple symbols representing a single value are identical whereas this is not true with strings. For example:
irb(main):007:0> :test.object_id
=> 83618
irb(main):008:0> :test.object_id
=> 83618
irb(main):009:0> :test.object_id
=> 83618
3 references to the symbol :test, all the same object.
irb(main):010:0> "test".object_id
=> -605770378
irb(main):011:0> "test".object_id
=> -605779298
irb(main):012:0> "test".object_id
=> -605784948
3 references to the string "test", all different objects.
This means that using symbols can potentially save a good bit of memory depending on the application. It is also faster to compare symbols for equality since they are the same object, comparing identical strings is much slower since the string values need to be compared instead of just the object ids.
I usually use strings for almost everything except things like hash keys where I really want a unique identifier, not a string

Ruby: Parsing a complex hash

I have a hash that goes multiple levels deep: http://gist.github.com/285350
I am trying to loop through each serving but I keep running into multiple nil[] errors even though the hash isn't nil.
For example:
food_hash["food"]["servings"]
Returns nil.[]
It might be because im half asleep but I can't seem to get down to the "serving_description"... could anyone help put me in the right direction?
I can't see get down to the "serving_description"
Note that (1) servings.serving is an array, and (2) food is not a key in the hash. Try this instead:
f["servings"]["serving"][0]["serving_description"]
=> "1 thin slice (yield after cooking)"
where f is the hash.
Is this what you're trying to do?
food_hash["servings"]["serving"][0]["serving_description"]

Resources