[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Suprising behaviour with "def property=" method

Farrel Lifson

2/24/2008 10:42:00 PM

I had a bit of a surprise with the following

class Foo
def bar(value)
@bar = value.upcase
end
end

f = Foo.new
my_bar = (f.bar = "bar")

I initially thought that my_bar would == "BAR" but in fact it equals
"bar". It seems no matter what the final value of the bar= method is
the return value is always the parameters. First time I've run into
this so I thought I would share and ask if anyone can think of anyway
to get around this?

Farrel

13 Answers

Farrel Lifson

2/24/2008 10:43:00 PM

0

This is on 1.8.6 on Gentoo Linux btw.

Farrel Lifson

2/24/2008 10:43:00 PM

0

On 25/02/2008, Farrel Lifson <farrel.lifson@gmail.com> wrote:
> I had a bit of a surprise with the following
>
> class Foo
> def bar(value)
> @bar = value.upcase
> end
> end

And of course the method should be

def bar=(value)
@bar = value.upcase
end

Philipp Hofmann

2/24/2008 10:58:00 PM

0

On Mon, Feb 25, 2008 at 07:41:31AM +0900, Farrel Lifson wrote:
> I had a bit of a surprise with the following
>
> class Foo
> def bar(value)
> @bar = value.upcase
> end
> end
>
> f = Foo.new
> my_bar = (f.bar = "bar")
>
> I initially thought that my_bar would == "BAR" but in fact it equals
> "bar". It seems no matter what the final value of the bar= method is
> the return value is always the parameters. First time I've run into
> this so I thought I would share and ask if anyone can think of anyway
> to get around this?
>
> Farrel
>


my_bar = f.send(:bar=, "bar")

g phil

Ezra Zygmuntowicz

2/25/2008 12:30:00 AM

0


On Feb 24, 2008, at 2:41 PM, Farrel Lifson wrote:

> I had a bit of a surprise with the following
>
> class Foo
> def bar(value)
> @bar = value.upcase
> end
> end
>
> f = Foo.new
> my_bar = (f.bar = "bar")
>
> I initially thought that my_bar would == "BAR" but in fact it equals
> "bar". It seems no matter what the final value of the bar= method is
> the return value is always the parameters. First time I've run into
> this so I thought I would share and ask if anyone can think of anyway
> to get around this?
>
> Farrel


This is just the way ruby works. It *always* returns the right hand
side of any method call ending in =. This is for consistency sake.
since you can write methods that look like assignment it keeps things
consistent to always return the rhs of any assignment.


Cheers-
- Ezra Zygmuntowicz
-- Founder & Software Architect
-- ezra@engineyard.com
-- EngineYard.com


7stud --

2/25/2008 1:04:00 AM

0

Farrel Lifson wrote:
> I had a bit of a surprise with the following
>
> class Foo
> def bar(value)
> @bar = value.upcase
> end
> end
>
> f = Foo.new
> my_bar = (f.bar = "bar")
>
> I initially thought that my_bar would == "BAR" but in fact it equals
> "bar". It seems no matter what the final value of the bar= method is
> the return value is always the parameters. First time I've run into
> this so I thought I would share and ask if anyone can think of anyway
> to get around this?
>
> Farrel

I'm not sure why the return value of calling bar= is the method
argument, but it makes sense to me that the return value is not the
*private* instance variable's value. If the return value were the
private instance variable's value, that would break the encapsulation
that a class is supposed to provide:

class Dog
def secret_code=(seed)
@secret_code = seed * 10 + 2
end
end

d = Dog.new
return_val = (d.secret_code=(3) )
puts return_val #should this reveal the secret code?
--
Posted via http://www.ruby-....

James Britt

2/25/2008 3:55:00 AM

0

Ezra Zygmuntowicz wrote:

> This is just the way ruby works. It *always* returns the right hand
> side of any method call ending in =. This is for consistency sake.


Except that it is inconsistent with the usually true, "The return value
of a method is the lest expression evaluated."

POLS, yada yada yada. Done deal.

Whatever it's benefits, though, it adds to list of "This is how Ruby
works, except when it doesn't."



--
James Britt

"The greatest obstacle to discovery is not ignorance, but the illusion
of knowledge."
- D. Boorstin

Arlen Cuss

2/25/2008 10:51:00 AM

0

[Note: parts of this message were removed to make it a legal post.]

On Mon, Feb 25, 2008 at 12:03 PM, 7stud -- <bbxx789_05ss@yahoo.com> wrote:

> class Dog
> def secret_code=(seed)
> @secret_code = seed * 10 + 2
> end
> end
>
> d = Dog.new
> return_val = (d.secret_code=(3) )
> puts return_val #should this reveal the secret code?
>

Yes. What would you like it to return? The point is, you're doing
d.secret_code = 3 -- you're saying the secret code *is* 3, so actually
setting it to something else is a bit misleading, don't you think?

class Dog
def generate_secret_code(seed)
@secret_code = seed * 10 + 2
self
end
end

This has the fun of allowing method chaining;
d = Dog.new
d.generate_secret_code(3).some_other_method_that_chains.yet_another(some,
args)

Arlen

Arlen Cuss

2/25/2008 10:53:00 AM

0

[Note: parts of this message were removed to make it a legal post.]

Hold up a second there;

Yes. What would you like it to return? The point is, you're doing
> d.secret_code = 3 -- you're saying the secret code *is* 3, so actually
> setting it to something else is a bit misleading, don't you think?


I clearly missed the boat here. I didn't know Ruby always returned the rval
of the expression.

You learn something new every day. :) Sorry for biting.

Arlen

marc

2/25/2008 12:11:00 PM

0

7stud -- said...
> Farrel Lifson wrote:
> > I had a bit of a surprise with the following
> >
> > class Foo
> > def bar(value)
> > @bar = value.upcase
> > end
> > end
> >
> > f = Foo.new
> > my_bar = (f.bar = "bar")
> >
> > I initially thought that my_bar would == "BAR" but in fact it equals
> > "bar". It seems no matter what the final value of the bar= method is
> > the return value is always the parameters. First time I've run into
> > this so I thought I would share and ask if anyone can think of anyway
> > to get around this?
> >
> > Farrel
>
> I'm not sure why the return value of calling bar= is the method
> argument, but it makes sense to me that the return value is not the
> *private* instance variable's value. If the return value were the
> private instance variable's value, that would break the encapsulation
> that a class is supposed to provide:
>
> class Dog
> def secret_code=(seed)
> @secret_code = seed * 10 + 2
> end
> end
>
> d = Dog.new
> return_val = (d.secret_code=(3) )
> puts return_val #should this reveal the secret code?
>

I concur; the OP's expected behaviour would break encapsulation.

class Foo
attr_reader :bar
def bar=(value)
@bar = value.upcase
end
end

f = Foo.new
my_bar = (f.bar = "bar")
puts my_bar # "bar"
puts f.bar # "BAR"

g = Foo.new
g.bar = "bar"
puts g.bar # "BAR"

--
Cheers,
Marc


James Britt

2/25/2008 5:26:00 PM

0

Arlen Cuss wrote:
> On Mon, Feb 25, 2008 at 12:03 PM, 7stud -- <bbxx789_05ss@yahoo.com> wrote:
>
>> class Dog
>> def secret_code=(seed)
>> @secret_code = seed * 10 + 2
>> end
>> end
>>
>> d = Dog.new
>> return_val = (d.secret_code=(3) )
>> puts return_val #should this reveal the secret code?
>>
>
> Yes. What would you like it to return? The point is, you're doing
> d.secret_code = 3 -- you're saying the secret code *is* 3, so actually
> setting it to something else is a bit misleading, don't you think?

Actually, you're saying "Send the message '.secret_code=(3)' to d"

It's up to d to decide what that means and what happens next.

Suppose secret_code=(x) checks that the given value meets some criteria
(say, is a positive int), and if not, uses the value 0. I might want
the method to then return a valid value, not simply what was passed in.



--
James Britt

"We are using here a powerful strategy of synthesis: wishful thinking."
- H. Abelson and G. Sussman
(in "The Structure and Interpretation of Computer Programs)