Rails - What happens when I convert an object into string? - ruby-on-rails

I was playing with Rails Console. By chance, I accidentally convert an object into a string.
Below are my codes.
Rails Console
user = User.find(1)
user.to_s # returns <User:0x00000103ada530>
My question is, What is <User:0x00000103ada530> ? Is it like an ID of User? Is I enter <User:0x00000103ada530> will I get back User.find(1)
Thanks

I could be wrong, but
0x00000103ada530
is address in memory
where you call User.new which is allocates memory space and the space has address: 0x00000103ada530
For example 2 instances of one class are not stores in the same place
class Test
end
t1 = Test.allocate # the same as Test.new, but just allocates a memory space for t1
t2 = Test.allocate
p t1 === t2 # false
p t1.inspect # "#<Test:0x007f17555ff398>"
p t2.inspect # "#<Test:0x007f17555ff370>"
If you need #to_s method for User you can set method
class User < ActiveRecord::Base
. . .
def to_s
"#{first_name} #{last_name}"
end
. . .
end
User.first.to_s # => John Doe

The #to_s method encodes the object's id as follows:
(obj.object_id * 2).to_s(16)
If you want to get from the result of #to_s back to the object, you could use ObjectSpace if you are on MRI:
o = Object.new
o2 = ObjectSpace._id2ref(o.to_s.split(":").last.hex / 2)
o and o2 will now be references to the same object.

Related

confused between instance variable and local variable

I recently started learning ruby and i am confused between instance variable and local variable and class variable. so , i recently written code which will find the largest palindrome in 1000 prime numbers.
code is:
def prime_large(number)
arr_prime = []
Prime.each(number) do |x|
new_arr_prime = arr_prime.push(x.to_s)
updated = new_arr_prime.select { |y| y.reverse == y }
end
p updated.max
end
p prime_large(1000)
error i got is:
undefined local variable or method `updated' for main:Object (NameError)
I know that updated is a local variable of prime so i can't access it outside it but i changed the code by replacing it with #updated as below:
def prime_large(number)
arr_prime = []
Prime.each(number) do |x|
new_arr_prime = arr_prime.push(x.to_s)
#updated = new_arr_prime.select { |y| y.reverse == y }
end
p #updated.max
end
p prime_large(1000)
after changing it , i got the output:
"929"
"929"
in my code , without creating a class how my instance variable ( #updated) is working . i am confused between local and instance variable . can anyone please explain me the differences and how they work ?
In your first example you created a local variable updated, that is only accessible within the scope of the block it is defined in. Meaning, it is available only within Prime.each(number) do end block.
In your second example you created instance variable #updated.
without creating a class how my instance variable ( #updated) is
working
It is because in Ruby everything occurs in the context of some object. Even though you did not created a class, you are being in the top-level context, in the context of object main.
Thus, any instance variables defined within top-level are instance variables of this object main.
So going back to your issue, to overcome it you'll want to just define the updated local variable outside the Prime.each(number) do end block:
def prime_large(number)
arr_prime = []
updated = nil # initialize local varialbe
Prime.each(number) do |x|
new_arr_prime = arr_prime.push(x.to_s)
updated = new_arr_prime.select { |y| y.reverse == y } # assign new value
end
p updated.max
end
p prime_large(1000)
To test it you can open irb or pry and check it yourself:
self # the object in the context of which you are currently
#=> main
self.class # main is an instance of class Object, any methods defined
# within main are added to Object class as instance methods
#=> Object
instance_variables # list of it's instance variables, none yet created
#=> []
#variable = 1 # create and instance variable
#=> 1
instance_variables # now created variable occurs in the list of current object's instance variables
#=> [:#variable]
def hello; :hello end # define method
#=> :hello
self.class.public_instance_methods(false) # list instance methods defined in Object
#=> [:hello]
What you now want to read about is lexical scopes in Ruby.

What is the difference between object.method(a,b) and method(a,b) in Ruby

I am very new to programming and am trying to learn Ruby. I can't quite get my head around methods at the moment. I uderstand that:
Methods allow me to execute a chunk of code without having to rewrite it, such a method looks like:
example_method
Arguments allow me to pass values into the code within the method that go in the place of the placeholders defined in the method. This way I can execute a set of code with different inputs. Methods with arguments look like:
example_method( x , y )
But I am confused about what an instantiation of a method on an object is actually doing. For example:
object.example_method( x, y )
What does this mean? Why is the method attached to an object with the period notation? Do we do this so we can reference Instance / Class variables of the object within our method? Is there any other reason to do this?
For the example if:
def example_method(x , y)
x * y
end
Will object.exaple_method(a , b) be the same as example_method(a , b) ?
Thanks for any help, sorry if I am not being clear.
Ruby is an Object Oriented language. This means that objects not only have members (=state) but also methods (=behavior). When you are calling a method on an object (is which case the object is called the caller) the method that runs is the method which corresponds to this object's type behavior.
When you are calling a method with no caller, self is implicitly the caller. From irb, self is considered main, or global scope.
Example:
def my_method(a)
"#{a} from main"
end
class A
def my_method(a)
"#{a} from A"
end
end
class B
def my_method(a)
"#{a} from B"
end
end
a = A.new
b = B.new
my_method(1)
# => "1 from main"
a.my_method(1)
# => "1 from A"
b.my_method(1)
# => "1 from B"
If I assume correctly what you're asking it's a class method vs an instance method
def Object
def self.example_method(x, y)
#this is a class method
x * y
end
def example_method(x,y)
#this is an instance method
x * y
end
end
So now we've defined them here's how we call them
#This called the class method
Object.example_method(3,3) => 9
#To call the instance method we have to have an instance
object = Object.new
object.example_method(3,3) => 9

counting regexp matches within the method

I have some code like below. comment method is called whenever some comment occurs in the html. Then, I am doing a regexp match, I want to count the number of matches within the parsed comments. Its printing like below
1
2
3
4
5
what I want is to just print 5 because thats the total number of matches. can someone help pls.
class PlainTextExtractor < Nokogiri::XML::SAX::Document
def comment(string)
# I am defining some regexp here
m = Regexp.new(re, Regexp::IGNORECASE);
if m.match(string)
$count += 1
puts $count
end
end
end
parser = Nokogiri::HTML::SAX::Parser.new(PlainTextExtractor.new)
parser.parse_memory(html)
Just move your puts $count out of the loop. You can put it at the end, after you call the parser.
If you are only interested in the number of matches you can do
m = Regexp.new(re, Regexp::IGNORECASE);
puts string.scan(m).length
One way is to make your class count the number of matches internally in an instance variable, eg #count. Then use attr_reader to create a method allowing you to read its value at the end. Also you don't need a global variable. Example (not tested):
class PlainTextExtractor < Nokogiri::XML::SAX::Document
attr_reader :count
def comment(string)
# I am defining some regexp here
m = Regexp.new(re, Regexp::IGNORECASE);
if m.match(string)
#count += 1
end
end
end
pt_extractor = PlainTextExtractor.new
parser = Nokogiri::HTML::SAX::Parser.new(pt_extractor)
parser.parse_memory(html)
puts pt_extractor.count

Is it sometimes not appropriate to use << on ActiveRecord associations?

Sometimes this works, and sometimes it doesn't:
class Foo
has_many :bars
end
class Bar
belongs_to :foo
end
foo = Foo.create
bar1 = Bar.create
bar2 = Bar.create
foo.bars << [bar1, bar2]
The fix is to assign them individually:
foo.bars << bar1
foo.bars << bar2
updated:
in the cases i'm experimenting with, foo and the bars are not new objects.
I haven't see a pattern in when it does or doesn't work. What's more, it seems like how rails deals with mass assignment (attr_accessible) here is odd. If I have code in place to raise an exception if mass assignment is attempted (to help me catch bugs during development), it doesn't work. But if I'm not raising those exceptions, it does work, even though foo_id is not on the attr_accessible list in either case.
Normally if you do "<< [x, y]" you don't push x and y to the array but rather a new array containing x and y (making it a multidimensional array):
> test = Array.new
=> []
> test << [1, 2]
=> [[1, 2]]
You might want to use "<< x << y" instead:
> test = Array.new
=> []
> test << 1 << 2
=> [1, 2]
For newly created objects, I'd recommend using the has_many association helper methods build or create:
foo = Foo.create
bar1 = foo.bars.create # saves the record
bar2 = foo.bars.build # does not save the record
bar2.save! # actually creates the object
These helpers can take a hash of attributes, just like regular create and new - the only difference is they automatically set up the association for you.
If the Bar object you are trying to add to foo already exists, my preference would be to set the association in the bar object:
foo = Foo.create # alternately Foo.find(1)
bar = Bar.find(1) # alternately Bar.new, but then use Foo.bars.build
bar.foo = foo
bar.save!
This way, it's a lot easier to track down problems, e.g. you can easily handle a validation error. The only difference with << is it keeps foo.bars up to date without reloading it - so if you need foo.bars to be immediately up to date with full list of bars (the old bars and the newly associated bars), you might want to use <<.
As a final footnote, you can also use the build helpers to create the whole thing at once:
foo = Foo.new
bar1 = Foo.bars.build
bar2 = Foo.bars.build
foo.save! # saves foo, bar1, and bar2 in one transaction,
# provided they are all valid
There's nothing wrong with the syntax foo.bars << [bar1,bar2]. Regarding the << method as defined on a has_many association, the Rails API says:
collection<<(object, …)
Adds one or more objects to the
collection by setting their foreign
keys to the collection’s primary key.
Note that this operation instantly
fires update sql without waiting for
the save or update call on the parent
object.
That may give you some clues as to the (apparently) inconsistent behavior.

In Ruby, how to write a method to display any object's instance variable names and its values

Given any object in Ruby (on Rails), how can I write a method so that it will display that object's instance variable names and its values, like this:
#x: 1
#y: 2
#link_to_point: #<Point:0x10031b298 #y=20, #x=38>
(Update: inspect will do except for large object it is difficult to break down the variables from the 200 lines of output, like in Rails, when you request.inspect or self.inspect in the ActionView object)
I also want to be able to print <br> to the end of each instance variable's value so as to print them out nicely on a webpage.
the difficulty now seems to be that not every instance variable has an accessor, so it can't be called with obj.send(var_name)
(the var_name has the "#" removed, so "#x" becomes "x")
Update: I suppose using recursion, it can print out a more advanced version:
#<Point:0x10031b462>
#x: 1
#y: 2
#link_to_point: #<Point:0x10031b298>
#x=38
#y=20
I would probably write it like this:
class Object
def all_variables(root=true)
vars = {}
self.instance_variables.each do |var|
ivar = self.instance_variable_get(var)
vars[var] = [ivar, ivar.all_variables(false)]
end
root ? [self, vars] : vars
end
end
def string_variables(vars, lb="\n", indent="\t", current_indent="")
out = "#{vars[0].inspect}#{lb}"
current_indent += indent
out += vars[1].map do |var, ivar|
ivstr = string_variables(ivar, lb, indent, current_indent)
"#{current_indent}#{var}: #{ivstr}"
end.join
return out
end
def inspect_variables(obj, lb="\n", indent="\t", current_indent="")
string_variables(obj.all_variables, lb, indent, current_indent)
end
The Object#all_variables method produces an array containing (0) the given object and (1) a hash mapping instance variable names to arrays containing (0) the instance variable and (1) a hash mapping…. Thus, it gives you a nice recursive structure. The string_variables function prints out that hash nicely; inspect_variables is just a convenience wrapper. Thus, print inspect_variables(foo) gives you a newline-separated option, and print inspect_variables(foo, "<br />\n") gives you the version with HTML line breaks. If you want to specify the indent, you can do that too: print inspect_variables(foo, "\n", "|---") produces a (useless) faux-tree format instead of tab-based indenting.
There ought to be a sensible way to write an each_variable function to which you provide a callback (which wouldn't have to allocate the intermediate storage); I'll edit this answer to include it if I think of something. Edit 1: I thought of something.
Here's another way to write it, which I think is slightly nicer:
class Object
def each_variable(name=nil, depth=0, parent=nil, &block)
yield name, self, depth, parent
self.instance_variables.each do |var|
self.instance_variable_get(var).each_variable(var, depth+1, self, &block)
end
end
end
def inspect_variables(obj, nl="\n", indent="\t", sep=': ')
out = ''
obj.each_variable do |name, var, depth, _parent|
out += [indent*depth, name, name ? sep : '', var.inspect, nl].join
end
return out
end
The Object#each_variable method takes a number of optional arguments, which are not designed to be specified by the user; instead, they are used by the recursion to maintain state. The given block is passed (a) the name of the instance variable, or nil if the variable is the root of the recursion; (b) the variable; (c) the depth to which the recursion has descended; and (d), the parent of the current variable, or nil if said variable is the root of the recursion. The recursion is depth-first. The inspect_variables function uses this to build up a string. The obj argument is the object to iterate through; nl is the line separator; indent is the indentation to be applied at each level; and sep separates the name and the value.
Edit 2: This doesn't really add anything to the answer to your question, but: just to prove that we haven't lost anything in the reimplementation, here's a reimplementation of all_variables in terms of each_variables.
def all_variables(obj)
cur_depth = 0
root = [obj, {}]
tree = root
parents = []
prev = root
obj.each_variable do |name, var, depth, _parent|
next unless name
case depth <=> cur_depth
when -1 # We've gone back up
tree = parents.pop(cur_depth - depth)[0]
when +1 # We've gone down
parents << tree
tree = prev
else # We're at the same level
# Do nothing
end
cur_depth = depth
prev = tree[1][name] = [var, {}]
end
return root
end
I feel like it ought to be shorter, but that may not be possible; because we don't have the recursion now, we have to maintain the stack explicitly (in parents). But it is possible, so the each_variable method works just as well (and I think it's a little nicer).
I see... Antal must be giving the advanced version here...
the short version then probably is:
def p_each(obj)
obj.instance_variables.each do |v|
puts "#{v}: #{obj.instance_variable_get(v)}\n"
end
nil
end
or to return it as a string:
def sp_each(obj)
s = ""
obj.instance_variables.each do |v|
s += "#{v}: #{obj.instance_variable_get(v)}\n"
end
s
end
or shorter:
def sp_each(obj)
obj.instance_variables.map {|v| "#{v}: #{obj.instance_variable_get(v)}\n"}.join
end
This is a quick adaptation of a simple JSON emitter I wrote for another question:
class Object
def inspect!(indent=0)
return inspect if instance_variables.empty?
"#<#{self.class}:0x#{object_id.to_s(16)}\n#{' ' * indent+=1}#{
instance_variables.map {|var|
"#{var}: #{instance_variable_get(var).inspect!(indent)}"
}.join("\n#{' ' * indent}")
}\n#{' ' * indent-=1}>"
end
end
class Array
def inspect!(indent=0)
return '[]' if empty?
"[\n#{' ' * indent+=1}#{
map {|el| el.inspect!(indent) }.join(",\n#{' ' * indent}")
}\n#{' ' * indent-=1}]"
end
end
class Hash
def inspect!(indent=0)
return '{}' if empty?
"{\n#{' ' * indent+=1}#{
map {|k, v|
"#{k.inspect!(indent)} => #{v.inspect!(indent)}"
}.join(",\n#{' ' * indent}")
}\n#{' ' * indent-=1}}"
end
end
That's all the magic, really. Now we only need some simple defaults for some types where a full-on inspect doesn't really make sense (nil, false, true, numbers, etc.):
module InspectBang
def inspect!(indent=0)
inspect
end
end
[Numeric, Symbol, NilClass, TrueClass, FalseClass, String].each do |klass|
klass.send :include, InspectBang
end
Like this?
# Get the instance variables of an object
d = Date.new
d.instance_variables.each{|i| puts i + "<br />"}
Ruby Documentation on instance_variables.
The concept is commonly called "introspection", (to look into oneself).

Resources