How does Mongoid know the difference between string values and symbol values? - ruby

Consider this example:
> x = User.first # or any persisted Mongoid::Document
=> #<User _id: 52014532a6356d1ac9000001, ...>
> x.set :foo, :bar
=> :bar
> x.set :foo2, 'bar'
=> "bar"
Note that "foo" and "foo2" are not declared in Ruby anywhere.
THEN, in a MongoDB shell:
> db.users.findOne({_id: ObjectId('52014532a6356d1ac9000001')})
{
"_id" : ObjectId("52014532a6356d1ac9000001"),
"foo" : "bar",
"foo2" : "bar",
...
}
BUT NOW, back in Ruby:
> x = User.find x.id; nil # to clear out any possibility of metadata on the instance
=> nil
> [x.read_attribute(:foo), x.read_attribute(:foo2)]
=> [:bar, "bar"]
How does it know?

Seens like BSON supports a symbol type for values, googling around
I found it:
https://github.com/mongodb/mongo-ruby-driver/wiki/FAQ#FrequentlyAskedQuestions-Ruby-IseethatBSONsupportsasymboltype.DoesthismeanthatIcanstoreRubysymbolsinMongoDB%3F

Related

Print memory address for Ruby array

irb> class A; end
=> nil
irb> a=A.new
=> "#<A:0x3094638>"
irb> a.inspect
=> "#<A:0x3094638>"
irb> b=[]
=> []
irb> b.inspect
=> "[]"
How to get memory address of an array object?
Use the method Object#object_id.
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. #object_id is a different concept from the :name notation, which returns the symbol id of name.
Example :-
Arup-iMac:arup_ruby $ irb
2.1.2 :001 > s = "I am a string"
=> "I am a string"
2.1.2 :002 > obj_id = s.object_id
=> 2156122060
2.1.2 :003 > ObjectSpace._id2ref obj_id
=> "I am a string"
2.1.2 :004 >

Why do I get an unexpected result with a ternary condition?

Can anyone explain to me this result please:
(trad = {foo: "Foo", bar:"Bar"}).has_key? :foo ? trad[:foo] : :foo
=> false
I expected it to return:
=> "Foo"
(trad = {foo: "Foo", bar:"Bar"}).has_key? :foo ? trad[:foo] : :foo
is like:
(trad = {foo: "Foo", bar:"Bar"}).has_key? (:foo ? trad[:foo] : :foo)
:foo ? trad[:foo] : :foo is evaluated to "Foo" because :foo is treated as truth value.
(trad = {foo: "Foo", bar:"Bar"}).has_key? "Foo" yields false because there's no "Foo" key.
Use following (override precedence by surrounding parentheses) to get the expected result:
>> ((trad = {foo: "Foo", bar:"Bar"}).has_key? :foo) ? trad[:foo] : :foo
=> "Foo"
Hash#fetch(key, default) seems more appropriate:
>> {foo: "Foo", bar:"Bar"}.fetch(:foo, :foo)
=> "Foo"
>> {foo: "Foo", bar:"Bar"}.fetch(:baz, :baz)
=> :baz
For want of parenthesis the app was lost...
(trad = {foo: "Foo", bar:"Bar"}).has_key? :foo ? trad[:foo] : :foo # => false
(trad = {foo: "Foo", bar:"Bar"}).has_key?(:foo) ? trad[:foo] : :foo # => "Foo"
I'd be careful writing code like this:
(trad = {foo: "Foo", bar:"Bar"})
It's not idiomatic, so use:
trad = {foo: "Foo", bar:"Bar"}
trad.has_key?...
The reason is, in times of panic, like at 2:45 AM when your coding partner gets a call about a system outage because he's on call, and dives into the code, that assignment could be hard to find.
In a code review I'd suggest something like this over the other:
trad = {foo: "Foo", bar:"Bar"}
trad.has_key?(:foo) ? trad[:foo]
: :foo # => "Foo"
Note: This only works on Ruby 1.9+.
That all said, I'd highly recommend using fetch as recommended by #falsetru.

Difference between :symbol and symbol:?

Just going through a tutorial, and thought somewhere I saw
first_name:
And another place
:first_name
Is this right? What is the difference?
The hash syntax changed in Ruby 1.9.2 to get closer to json.
So:
{ :foo => "bar" }
Is the same as:
{ foo: "bar" }
In all other cases, the colon must come first.
:first_name is a symbol, while first_name: is a Hash key in the new Ruby 1.9.2 syntax.
Hash keys are then converted to symbols:
>> a = { foo: 10 , bar: 20 }
=> {:foo=>10, :bar=>20}
It is the same as writing:
>> a = { :foo => 10, :bar => 20 }
=> {:foo=>10, :bar=>20}

Parse arguments in string format into an array, but respect the nested commas in default params

I am writing a ruby method that takes a string like this
"foo = { :foo => 'bar', :baz => \"{'foo' : 'bar', 'bar' : 'biff' }\" :bar => 'baz' }, bar, baz = \"('foo,bar,baz')\", &block"
and returns an array like this:
["foo = { :foo => 'bar', :baz => \"{'foo' : 'bar', 'bar' : 'biff' }\" :bar => 'baz' }", "bar", "baz = \"('foo,bar,baz')\"", "&block"]
However, so far I am unable to split the string correctly, my best effort still breaks the string on internal hashes e.g.
"foo = { :foo => 'bar', :baz => \"{'foo' : 'bar', 'bar' : 'biff' }\" :bar => 'baz' }, bar, "baz = \"('foo,bar,baz')\", &block".scan(/(?:[^,(]|\([^)]*\))+/)
Which produces:
["foo = { :foo => 'bar'", " :baz => \"{'foo' : 'bar'", " 'bar' : 'biff' }\" :bar => 'baz' }", " bar", " baz = \"('foo,bar,baz')\"", " &block"]
I think the regex i am using is close but i am not sure how to check for both parenthesis and curly brackets. Presently, the regex only searches for parentheses.
This is my current regex:
/(?:[^,(]|\([^)]*\))+/
Any help is greatly appreciated.
this does not suit you?
string.split(',')

Finding out variable class and difference between Hash and Array

Is it possible to clearly identify a class of variable?
something like:
#users.who_r_u? #=>Class (some information)
#packs.who_r_u? #=> Array (some information)
etc.
Can someone provide clear short explanation of difference between Class, Hash, Array, Associated Array, etc. ?
You can use:
#users.class
Test it in irb:
1.9.3p0 :001 > 1.class
=> Fixnum
1.9.3p0 :002 > "1".class
=> String
1.9.3p0 :003 > [1].class
=> Array
1.9.3p0 :004 > {:a => 1}.class
=> Hash
1.9.3p0 :005 > (1..10).class
=> Range
Or:
1.9.3p0 :010 > class User
1.9.3p0 :011?> end
=> nil
1.9.3p0 :012 > #user = User.new
=> #<User:0x0000010111bfc8>
1.9.3p0 :013 > #user.class
=> User
These were only quick irb examples, hope it's enough to see the use of .class in ruby.
You could also use kind_of? to test wheter its receiver is a class, an array or anything else.
#users.kind_of?(Array) # => true
You can find these methods in Ruby document http://ruby-doc.org/core-1.9.3/Object.html
#user.class => User
#user.is_a?(User) => true
#user.kind_of?(User) => true
found helpful: <%= debug #users %>
A difference between Class and Hash? They are too different to even provide normal answer. Hash is basically an array with unique keys, where each key has its associated value. That's why it's also called associative array.
Here is some explanation:
array = [1,2,3,4]
array[0] # => 1
array[-1] # => 4
array[0..2] # => [1,2,3]
array.size # => 4
Check out more Array methods here: http://ruby-doc.org/core-1.9.3/Array.html
hash = {:foo => 1, :bar => 34, :baz => 22}
hash[:foo] # => 1
hash[:bar] # => 34
hash.keys # => [:baz,:foo,:bar]
hash.values # => [34,22,1]
hash.merge :foo => 3921
hash # => {:bar => 34,:foo => 3921,:baz => 22 }
Hash never keeps order of the elments you added to it, it just preserves uniqueness of keys, so you can easily retreive values.
However, if you do this:
hash.merge "foo" => 12
you will get
hash # => {:bar => 34, baz => 22, "foo" => 12, :foo => 2}
It created new key-value pair since :foo.eql? "foo" returns false.
For more Hash methods check out this: http://www.ruby-doc.org/core-1.9.3/Hash.html
Class object is a bit too complex to explain in short, but if you want to learn more about it, reffer to some online tutorials.
And remember, API is your friend.

Resources