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?

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

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?

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

···

On Saturday 01 September 2012 Rubyist Rohit wrote

Rubyist Rohit 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'.

···

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

@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?

···

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

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.

···

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

Hi,

@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

···

On 2012-09-01, at 8:54 AM, Rubyist Rohit <lists@ruby-forum.com> wrote:

Cheers,
Bob

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

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 `<main>'
irb(main):014:0> c.name
=> nil

Kind regards

robert

···

On Sat, Sep 1, 2012 at 1:59 PM, Rubyist Rohit <lists@ruby-forum.com> 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'?

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

Rubyist Rohit 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.

···

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

And there's an even shorter way to do this

Customer = Struct.new :name

Kind regards

robert

···

On Sat, Sep 1, 2012 at 3:30 PM, Bob Hutchison <hutch-lists@recursive.ca> wrote:

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

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

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

Bob Hutchison 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.

···

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

@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?

···

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

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 2012-09-01, at 2:46 PM, Brian Candler <lists@ruby-forum.com> wrote:

Bob Hutchison 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 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

···

On Sat, Sep 1, 2012 at 2:20 PM, Rubyist Rohit <lists@ruby-forum.com> wrote:

@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?

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