Constructor or a Method

Take for instance this code:

======== [CODE] =======
def Customer
attr_accessor :name

def name
@name
end

def name(=str)
@name = str
end
end

I want to know:

(1) Is ‘name’ a constructor or a method?
(2) In case I ignore ‘=’ in second method, will it work? Why ‘=’ is
necessary?

On Saturday 01 September 2012 Rubyist R. wrote

def name(=str)
@name = str
end
end

I want to know:

(1) Is ‘name’ a constructor or a method?
It’s a normal method. What you’d call a “constructor” in other
languages, in
ruby is the initialize method.

(2) In case I ignore ‘=’ in second method, will it work? Why ‘=’ is
necessary?
If you omit the = in the second method, you’ll define a method called
“name”
which takes one argument and makes the instance variable @name point to
the
str object. This will override the previously defined name method. Also,
you
won’t be able to do something like:

Customer.new.name = ‘x’

but only

Customer.new.name ‘x’

which, depending on circumstances, may be unexpected.

Note that both the method definitions are useless here, as using
attr_accessor
already creates two methods doing exactly what your hand-written methods
do.

I hope this helps

Stefano

Rubyist R. wrote in post #1074150:

def name(=str)

I think you mean

def name=(str)

(2) In case I ignore ‘=’ in second method, will it work? Why ‘=’ is
necessary?

It’s part of the method name.

obj.name = 123 # syntactic sugar, calls the name= method
obj.name=(123) # same
obj.send(:name=,123) # same

Note that in the first two cases, the value of the expression is forced
to be the value of the argument (not the return value from the method).

class Foo; def name=(x); @name=x; return 999; end; end
=> nil

obj = Foo.new
=> #Foo:0x1031a0438

obj.name = 123
=> 123

obj.name=(456)
=> 456

obj.send(:name=,789)
=> 999

obj
=> #<Foo:0x1031a0438 @name=789>

This is to avoid surprises when chaining together expressions which look
like ‘assignment’.

On Sat, Sep 1, 2012 at 1:59 PM, Rubyist R. [email protected]
wrote:

Note that both the method definitions are useless here, as using
attr_accessor
already creates two methods doing exactly what your hand-written methods
do.

Stefano

@Stefano;

What if I use ‘attr_reader’ instead of ‘attr_accessor’?

You only get method #name and not also #name=.

Btw, you can easily try these things out in IRB:

irb(main):007:0> class Customer; attr_accessor :name; end
=> nil
irb(main):008:0> c = Customer.new
=> #Customer:0x2029f5c0
irb(main):009:0> c.name = “foo”
=> “foo”
irb(main):010:0> c.name
=> “foo”
irb(main):011:0> class C2; attr_reader :name; end
=> nil
irb(main):012:0> c = C2.new
=> #C2:0x202a2914
irb(main):013:0> c.name = “foo”
NoMethodError: undefined method name=' for #<C2:0x202a2914> from (irb):13 from /usr/local/bin/irb19:12:in
irb(main):014:0> c.name
=> nil

Kind regards

robert

Note that both the method definitions are useless here, as using
attr_accessor
already creates two methods doing exactly what your hand-written methods
do.

Stefano

@Stefano;

What if I use ‘attr_reader’ instead of ‘attr_accessor’?

Is ‘attr_accessor’ similar to auto-properties in .NET? I am talking
about those getters and setters in .NET.

Rubyist R. wrote in post #1074199:

What if I use ‘attr_reader’ instead of ‘attr_accessor’?

This will only define a getter. And attr_writer will only define a
setter. attr_accessor does both.

Is ‘attr_accessor’ similar to auto-properties in .NET? I am talking
about those getters and setters in .NET.

Looks like it.

@Robert:

So what I followed is if ‘attr_accessor’ is used, there is no need to
create Properties. But the confusion now arises how Ruby properties are
different than methods. The way of writing both are same.

In my code in original post, I have a property:

def name
@name
end

Is this a property or a method?

@Robert,

This is quite confusing in Ruby as method and properties look alike.

To correct my original post, shall I remove ‘attr_accessor’ to make
sense?

On Sat, Sep 1, 2012 at 2:20 PM, Rubyist R. [email protected]
wrote:

end

Is this a property or a method?

“name” is a method and “@name” is an instance variable. You can view
this as a read only property. It’s the same as just doing
“attr_reader :name” btw. “Method” and “instance variable” are
technical terms while “property” is more abstract - it describes the
concept that an instance has some properties (which are typically
implemented with accessor methods and instance variables).

Kind regards

robert

Hi,

On 2012-09-01, at 8:54 AM, Rubyist R. [email protected] wrote:

@Robert,

This is quite confusing in Ruby as method and properties look alike.

You’ve got a terminology thing going on and this is confusing you I
think. There are no such thing as ‘properties’ in Ruby (google it and
you can read about the magical healing properties of the ruby gemstone
:slight_smile:

Generally speaking you’ve got attributes and methods. There are two
kinds of attributes (class and instance) but you’re talking about
instance attributes. Attributes are private to an object, only the
specific instance has access to them. They are idiomatically and
optionally exposed to other objects through ‘accessor methods’ which are
just methods with a naming convention, nothing at all special about
them. Ruby provides three ways to concisely ask Ruby to generate
accessor methods for you: attr_reader, attr_writer, attr_accessor.
Idiomatic Ruby is to use these automated accessors. However, it’s
possible that you have something more complex you have to do in which
case you’d write your own accessors.

To correct my original post, shall I remove ‘attr_accessor’ to make
sense?

Since you are not doing anything special, use idiomatic Ruby:

======== [CODE] =======
def Customer
attr_accessor :name
end

Cheers,
Bob

Bob H. wrote in post #1074214:

You’ve got a terminology thing going on and this is confusing you I
think. There are no such thing as ‘properties’ in Ruby (google it and
you can read about the magical healing properties of the ruby gemstone
:slight_smile:

Generally speaking you’ve got attributes and methods.

IMO it would be clearer and more accurate to say “instance variables”
and “methods”, but otherwise this is correct.

@name is an instance variable, which you can only access in the context
of a specific object (usually within an instance method of the class of
that object)

Methods like ‘name’ and ‘name=’ are just methods, which in simple
classes might just return the value of @name and set the value of @name.
If that’s all you need, then attr_* will write those methods for you.
But they are still normal methods.

On 2012-09-01, at 2:46 PM, Brian C. [email protected] wrote:

Bob H. wrote in post #1074214:

You’ve got a terminology thing going on and this is confusing you I
think. There are no such thing as ‘properties’ in Ruby (google it and
you can read about the magical healing properties of the ruby gemstone
:slight_smile:

Generally speaking you’ve got attributes and methods.

IMO it would be clearer and more accurate to say “instance variables”
and “methods”, but otherwise this is correct.

Could be, but since the shortcuts use ‘attr_’ I went with ‘attribute’.
It’s a point-of-view thing: public vs internal. ‘Instance variable’ is
an internal thing, even an implementation thing. ‘Attribute’ is a public
thing, even a conceptual thing.

Which reminds me. I wanted to mention something about constructors. But
I won’t. That’d just be opening up a can of worms. I’m glad I forgot.
I’ll recommend the OP gets a decent book on Ruby that explains all this
systematically. Personally I like David Black’s “The Well Grounded
Rubyist” from Manning.

Cheers,
Bob

On Sat, Sep 1, 2012 at 3:30 PM, Bob H. [email protected]
wrote:

Since you are not doing anything special, use idiomatic Ruby:

======== [CODE] =======
def Customer
attr_accessor :name
end

And there’s an even shorter way to do this

Customer = Struct.new :name

Kind regards

robert