Can't change the value of self

  • Thread starter Jonathan Leighton
  • Start date
J

Jonathan Leighton

This code:

--------------
class Time

# Rounds a time sensibly.
# Currently just hour is supported (as that's the only one needed)
def round_to(unit = :hour)
unless min == 0
new_hour = hour
new_hour += 1 if min > 30
time = Time.local(year, month, day, new_hour)
end
time
end

def round_to!(*args)
self = round_to *args
end

end
--------------

Throws this error:

Can't change the value of self (SyntaxError)
self = round_to *args

Why doesn't it work? What can I do instead?

Thanks
 
J

James Britt

Jonathan said:
Can't change the value of self (SyntaxError)
self = round_to *args

Why doesn't it work? What can I do instead?

"Destructive" methods must alter self using that self's existing
destructive methods.


James

--

http://www.ruby-doc.org - Ruby Help & Documentation
http://www.artima.com/rubycs/ - Ruby Code & Style: Writers wanted
http://www.rubystuff.com - The Ruby Store for Ruby Stuff
http://www.jamesbritt.com - Playing with Better Toys
http://www.30secondrule.com - Building Better Tools
 
H

Hal Fulton

James said:
"Destructive" methods must alter self using that self's existing
destructive methods.

To which we should add: Time has no destructive methods, since
Time objects are immutable.

But someone once created a MutableTime class -- anyone recall
who/when/where and whether it's complete?


Hal
 
G

gwtmp01

Can't change the value of self (SyntaxError)
self = round_to *args

Why doesn't it work? What can I do instead?

Instead of

a.round_to!:)hour)

just write

a = a.round_to:)hour)

Or maybe a different name would help:

a = a.closest:)hour)


Gary Wright
 
W

Wilson Bilkovich

To which we should add: Time has no destructive methods, since
Time objects are immutable.

But someone once created a MutableTime class -- anyone recall
who/when/where and whether it's complete?

This is why I can't do:
class Fixnum
def double!
self *=3D 2
end
end
..right? Too bad.

Speaking of methods.. is there a way to do:
class Something
def <<(a, b)
# do something with a and b
end
end

s =3D Something.new
s << 'a', 'b'
results in a syntax error.

Is that another of those YACC limitations?
 
G

George Ogata

Wilson Bilkovich said:
Speaking of methods.. is there a way to do:
class Something
def <<(a, b)
# do something with a and b
end
end

s = Something.new
s << 'a', 'b'
results in a syntax error.

You could do s.<<('a', 'b'), but it seems unrubyish. Perhaps you
could settle for:

s << ['a', 'b']
Is that another of those YACC limitations?

Hmmm, I don't know if it's a limitation, but it could get confusing.
Consider:

four, three = 1 << 2, 3
arr = [x << 1, x << 2]

And if you do it for `<<', then what about `+', `-', `%'? If you do
do it for those, then you start to lose really basic stuff like:

arr = [a + 1, b + 1]
b, a = a % b, b until b == 0
 
H

Hal Fulton

Jonathan said:
Thanks very much for this explanation, the restriction makes a lot more
sense to me now.

You should also know that more complex objects (as you know) can
often change their state. In particular, Array and String both
implement a replace method, which totally replaces their contents.
But even then, the object id stays the same.


Hal
 
H

Henrik Martensson

Immutable classes are less prone to bugs than mutable classes. This is
because they have a single state. They are also thread safe.

It is good practise to favor immutability when there are no compelling
reasons for making a class mutable.

A Time object represents an instance in time. Making it mutable could
easily get confusing. Consider:

time = MutableTime.at(946702800)
rocket.launch_time = time
...
time.change(946701565) # Changes the launch time of the rocket


The launch time of the rocket can be changed without setting the
launch_time property explicitly. This is a potential source of bugs.

/Henrik
 
H

Hal Fulton

Henrik said:
Immutable classes are less prone to bugs than mutable classes. This is
because they have a single state. They are also thread safe.

It is good practise to favor immutability when there are no compelling
reasons for making a class mutable.

A Time object represents an instance in time. Making it mutable could
easily get confusing. Consider:

time = MutableTime.at(946702800)
rocket.launch_time = time
...
time.change(946701565) # Changes the launch time of the rocket


The launch time of the rocket can be changed without setting the
launch_time property explicitly. This is a potential source of bugs.


Thanks, Henrik. That's a great discussion and a great example.


Hal
 
G

Gavin Kistner

To which we should add: Time has no destructive methods, since
Time objects are immutable.

But someone once created a MutableTime class -- anyone recall
who/when/where and whether it's complete?

That'd be me, and it's documented at http://phrogz.net/RubyLibs/rdoc/
classes/MutableTime.html and available for download at http://
phrogz.net/RubyLibs/MutableTime.rb

As to whether it's 'complete'...I dunno. I nominally labeled it
v1.0.5, but who knows what that means :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top