How is this possible (Class.new.chain_method)

class Restaurant

  attr_accessor :name, :cuisine, :price

  def initialize(args={})
    @name = args[:name] || ""
    @cuisine = args[:cuisine] || ""
    @price = args[:price] || ""
  end

  def self.bracket_method
    args = {}
    args[:name] = "Burger store"
    args[:cuisine] = "Fast Food"
    args[:price] = "10"
    args[:wrongz] = "this isn't printed"
    return args
  end

  def chain_method
    @name = "Pizza store"
    @cuisine = "Fastest Food"
    @price = "5"
    @wrongz = "this is printed"
    puts self.inspect
    return self
  end

  x = Restaurant.new(bracket_method)
  puts x.inspect
  puts x.class
  puts
  y = Restaurant.new.chain_method
  puts y.inspect
  puts y.class

end

···

-----------------------------------------------------------
"bracket_method" is logical, but what is going on in case of
"chain_method" ?
Did I instantiate object "y" of class "Restaurant" without
initialization ?
How is that possible ?

--
Posted via http://www.ruby-forum.com/.

I think I didn't get right your question, perhaps because my "not so
good" english.

But, step-by-step it would be ...

y = Restaurant.new.chain_method

is the same as ...

rest = Restaurant.new # So, here, you have alread "initialized" the object.
y = rest.chain_method

'y' will be the same object as 'rest' because the chain_method is
returning self.

Is this the question? If not, sorry for not helping much.

Best regards,
Abinoam Jr.

···

On Tue, Oct 22, 2013 at 5:34 PM, Stu P. D'naim <lists@ruby-forum.com> wrote:

class Restaurant

  attr_accessor :name, :cuisine, :price

  def initialize(args={})
    @name = args[:name] || ""
    @cuisine = args[:cuisine] || ""
    @price = args[:price] || ""
  end

  def self.bracket_method
    args = {}
    args[:name] = "Burger store"
    args[:cuisine] = "Fast Food"
    args[:price] = "10"
    args[:wrongz] = "this isn't printed"
    return args
  end

  def chain_method
    @name = "Pizza store"
    @cuisine = "Fastest Food"
    @price = "5"
    @wrongz = "this is printed"
    puts self.inspect
    return self
  end

  x = Restaurant.new(bracket_method)
  puts x.inspect
  puts x.class
  puts
  y = Restaurant.new.chain_method
  puts y.inspect
  puts y.class

end
-----------------------------------------------------------
"bracket_method" is logical, but what is going on in case of
"chain_method" ?
Did I instantiate object "y" of class "Restaurant" without
initialization ?
How is that possible ?

--
Posted via http://www.ruby-forum.com/\.

I know that, but I thought that by running .chain_method_two, instance
variables values should be changed from nil to newly assigned strings
... I hate it when I think I finally understood something, but it turns
out that it doesn't work the way I think it will ... I guess I'm gonna
go back and check out again stuff about reader/writer methods.
Thanks for your time !

···

--
Posted via http://www.ruby-forum.com/.

class Restaurant

  attr_accessor :name, :cuisine, :price

  def initialize(args={})
    @name = args[:name]
    @cuisine = args[:cuisine]
    @price = args[:price]
  end

  def chain_method_two
    @name = "www store"
    @cuisine = "www Food"
    @price = "5w"
    @wrongz = "www is printed"
  end
end

x = Restaurant.new
x.chain_method_two
puts x.inspect

y = Restaurant.new.chain_method_two
puts y.inspect

···

---------------------------------------------------
you said:

y = Restaurant.new.chain_method
is the same as ...
rest = Restaurant.new
y = rest.chain_method

but from my code above, x - works, y - just returns string ... so, now
it
seems it is not the same thing

--
Posted via http://www.ruby-forum.com/\.

I think I didn't get right your question, perhaps because my "not so
good" english.

But, step-by-step it would be ...

y = Restaurant.new.chain_method

is the same as ...

rest = Restaurant.new # So, here, you have alread "initialized" the object.
y = rest.chain_method

'y' will be the same object as 'rest' because the chain_method is
returning self.

Expanding a little bit on what Abinoam Jr. said:

  def initialize(args={})
    @name = args[:name] || ""
    @cuisine = args[:cuisine] || ""
    @price = args[:price] || ""
  end

The initialize method is called internally by "new", passing all the
arguments you passed to "new". In this case you are not passing any,
so initialize is called with no arguments. Now, if you look closely at
the definition of your initialize, you have an optional argument with
a default value, so when you don't pass anything, "args" is an empty
hash, and so @name, @cuisine and @price are initialized to empty
values. When you then call "chain_method" on an object initialized
this way, those variables are assigned to the values "Pizza store" and
so on.

Hope this helps,

Jesus.

···

On Wed, Oct 23, 2013 at 5:54 AM, Abinoam Jr. <abinoam@gmail.com> wrote:

How are you checking that they are nil, because you lose the reference
to the object you modify:

w = Restaurant.new.chain_method_two

if you do this, Restaurant.new will return the instance, on which you
call chain_method_two, but you don't keep a reference to the instance,
so how do you know the values were not changed?

2.0.0p195 :001 > class Restaurant
2.0.0p195 :002?> def chain_two
2.0.0p195 :003?> @a = 3
2.0.0p195 :004?> @b = "something"
2.0.0p195 :005?> end
2.0.0p195 :006?> end
=> nil
2.0.0p195 :007 > value = Restaurant.new.chain_two
=> "something"
2.0.0p195 :008 > value
=> "something"
2.0.0p195 :009 > reference = Restaurant.new
=> #<Restaurant:0x0000000266e610>
2.0.0p195 :010 > reference.chain_two
=> "something"
2.0.0p195 :011 > reference
=> #<Restaurant:0x0000000266e610 @a=3, @b="something">

Jesus.

···

On Wed, Oct 23, 2013 at 1:41 PM, Stu P. D'naim <lists@ruby-forum.com> wrote:

I know that, but I thought that by running .chain_method_two, instance
variables values should be changed from nil to newly assigned strings
... I hate it when I think I finally understood something, but it turns
out that it doesn't work the way I think it will ... I guess I'm gonna
go back and check out again stuff about reader/writer methods.
Thanks for your time !

As others have said already: the reason is that #chain_method_two does
not return self.

Cheers

robert

···

On Wed, Oct 23, 2013 at 2:05 PM, Stu P. D'naim <lists@ruby-forum.com> wrote:

class Restaurant

  attr_accessor :name, :cuisine, :price

  def initialize(args={})
    @name = args[:name]
    @cuisine = args[:cuisine]
    @price = args[:price]
  end

  def chain_method_two
    @name = "www store"
    @cuisine = "www Food"
    @price = "5w"
    @wrongz = "www is printed"
  end
end

x = Restaurant.new
x.chain_method_two
puts x.inspect

y = Restaurant.new.chain_method_two
puts y.inspect
---------------------------------------------------
you said:

y = Restaurant.new.chain_method
is the same as ...
rest = Restaurant.new
y = rest.chain_method

but from my code above, x - works, y - just returns string ... so, now
it seems it is not the same thing

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

"Jesús Gabriel y Galán" <jgabrielygalan@gmail.com> wrote in post
#1125295:

The initialize method is called internally by "new", passing all the
arguments you passed to "new". In this case you are not passing any,
so initialize is called with no arguments. Now, if you look closely at
the definition of your initialize, you have an optional argument with
a default value

ahh, I forgot about significance of default value, I was wondering why I
don't get error, but when I remove args = {}, there it is. For a moment
I thought that by doing Class.new.chain_method I was overriding .new
Thanks !

Abinoam Jr. wrote in post #1125275:

y = Restaurant.new.chain_method

is the same as ...

rest = Restaurant.new
y = rest.chain_method

'y' will be the same object as 'rest' because the chain_method is
returning self.

This explains a lot, thank you ! Now, there is only one little thing
that I still don't understand ...

if I add to my code something like this:

···

---------------------------
def chain_method_two
    @name = "www store"
    @cuisine = "www Food"
    @price = "5w"
    @wrongz = "www is printed"
end

w = Restaurant.new.chain_method_two
puts w.inspect
---------------------------
now I get new object (because I'm not returning self) but:
@name, @couisine and @price are all equal to nil ... shouldn't they be
equal to strings from chain_method_two ?
It's supposed to be a setter method

--
Posted via http://www.ruby-forum.com/\.

Methods in Ruby return the value of the last expression. In your case
the last expression is @wrongz = "www is printed", which evaluates to
the String "www is printed", so that's what the method returns.

Jesus.

···

On Wed, Oct 23, 2013 at 12:59 PM, Stu P. D'naim <lists@ruby-forum.com> wrote:

"Jesús Gabriel y Galán" <jgabrielygalan@gmail.com> wrote in post
#1125295:

The initialize method is called internally by "new", passing all the
arguments you passed to "new". In this case you are not passing any,
so initialize is called with no arguments. Now, if you look closely at
the definition of your initialize, you have an optional argument with
a default value

ahh, I forgot about significance of default value, I was wondering why I
don't get error, but when I remove args = {}, there it is. For a moment
I thought that by doing Class.new.chain_method I was overriding .new
Thanks !

Abinoam Jr. wrote in post #1125275:

y = Restaurant.new.chain_method

is the same as ...

rest = Restaurant.new
y = rest.chain_method

'y' will be the same object as 'rest' because the chain_method is
returning self.

This explains a lot, thank you ! Now, there is only one little thing
that I still don't understand ...

if I add to my code something like this:
---------------------------
def chain_method_two
    @name = "www store"
    @cuisine = "www Food"
    @price = "5w"
    @wrongz = "www is printed"
end

w = Restaurant.new.chain_method_two
puts w.inspect
---------------------------
now I get new object (because I'm not returning self) but:
@name, @couisine and @price are all equal to nil ... shouldn't they be
equal to strings from chain_method_two ?
It's supposed to be a setter method