Forum: Ruby Can't change the value of self

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
9d4ec8946f933a18a1d15b094cc3c425?d=identicon&s=25 Jonathan Leighton (Guest)
on 2006-01-02 01:39
(Received via mailing list)
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
Bc6d88907ce09158581fbb9b469a35a3?d=identicon&s=25 James Britt (Guest)
on 2006-01-02 01:42
(Received via mailing list)
Jonathan Leighton wrote:
> 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
C1bcb559f87f356698cfad9f6d630235?d=identicon&s=25 Hal Fulton (Guest)
on 2006-01-02 01:48
(Received via mailing list)
James Britt wrote:
> Jonathan Leighton wrote:
>
>> 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.

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
9d4ec8946f933a18a1d15b094cc3c425?d=identicon&s=25 Jonathan Leighton (Guest)
on 2006-01-02 02:12
(Received via mailing list)
On Mon, 2006-01-02 at 09:47 +0900, Hal Fulton wrote:
> > 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?

Thanks for the replies. Why is Time immutable (presumably it's
deliberately designed like that)? The MutableTime class sounds
interesting but it's probably overkill for what I wanted to do -- I'll
just modify variables at a higher level.

Thanks
E7559e558ececa67c40f452483b9ac8c?d=identicon&s=25 unknown (Guest)
on 2006-01-02 02:19
(Received via mailing list)
On Jan 1, 2006, at 7:37 PM, Jonathan Leighton wrote:
> 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
25e11a00a89683f7e01e425a1a6e305c?d=identicon&s=25 Wilson Bilkovich (Guest)
on 2006-01-02 04:22
(Received via mailing list)
On 1/1/06, Hal Fulton <hal9000@hypermetrics.com> wrote:
> > 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?
>

This is why I can't do:
class Fixnum
  def double!
    self *= 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 = Something.new
s << 'a', 'b'
results in a syntax error.

Is that another of those YACC limitations?
918c6daad03c85e51ad1a11f57017947?d=identicon&s=25 Devin Mullins (Guest)
on 2006-01-02 05:16
(Received via mailing list)
Wilson Bilkovich wrote:

>..right?  Too bad.
>
>
Well, that, and what would "2.double!" do?

>
>
My guess is you're out of luck, there. But you could change it to take s
<< ['a','b'] or s << 'a' << 'b'.

Devin
851246810c70dbfcc1815c636b054562?d=identicon&s=25 George Ogata (Guest)
on 2006-01-02 08:23
(Received via mailing list)
Wilson Bilkovich <wilsonb@gmail.com> writes:

>
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
A4327ebc799afb6896c5b224d76f9b9e?d=identicon&s=25 Ron Jeffries (Guest)
on 2006-01-02 11:33
(Received via mailing list)
On Mon, 2 Jan 2006 09:37:45 +0900, Jonathan Leighton
<lists@turnipspatch.com>
wrote:

>Can't change the value of self (SyntaxError)
>    self = round_to *args
>
>Why doesn't it work? What can I do instead?

One way of thinking about reassigning self is if you imagine in a
numeric class
saying

def double
  self *= 2
end

That would amount to saying, if we did 1.double,
  1 becomes 2
which would mean that 1+1 would thereafter be 4, and that would be bad.

What we need is not the value 1 to become 2, but to get the value 2 back
when we
say 1.double. So we say

def double
  return self*2
end

or, since "return" is implied

def double
 self*2
end

In general in OO, an object can change its contents, but it cannot
change its
"self". What should happen in this program?

one = 1
another_one = 1
assert_equal(2, one+one)
assert_equal(2, another_one+another_one)
one.double
assert_equal(4, one+one)
assert_equal(???,another_one+another_one)
assert_equal(???, 1+1)

When we double one, if the self*=2 thing worked, the ??? asserts would
also find
4. We might be able to understand another_one being 2, but to have all
occurrences of 1+1 in the program turn into 4 ... that would be bad.

Certain objects are called "value objects", and the idea is that like
numbers,
they never change value. For many objects it is a design choice whether
or not
to make them value objects, even if they are quite complex. For example,
in the
articles I'm currently writing on extended set theory on my site, I'm
moving in
the direction of making my sets value objects. They are essentially
arbitrarily
large collections of records (like relational database relations), and
most DB
apps think of relations as mutable. I'm going to make a different
decision,
namely that any set, once created, is a constant. It'll be interesting
to see
what happens.
9d4ec8946f933a18a1d15b094cc3c425?d=identicon&s=25 Jonathan Leighton (Guest)
on 2006-01-02 13:06
(Received via mailing list)
Thanks very much for this explanation, the restriction makes a lot more
sense to me now.

Jon
C1bcb559f87f356698cfad9f6d630235?d=identicon&s=25 Hal Fulton (Guest)
on 2006-01-02 20:45
(Received via mailing list)
Jonathan Leighton wrote:
> 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
Ded98dc06a045924f0d48b2e46fdf229?d=identicon&s=25 Henrik Martensson (Guest)
on 2006-01-05 02:33
(Received via mailing list)
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
C1bcb559f87f356698cfad9f6d630235?d=identicon&s=25 Hal Fulton (Guest)
on 2006-01-05 04:31
(Received via mailing list)
Henrik Martensson wrote:
> 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
Ec9233451f7c6ba37a83388b87a1f565?d=identicon&s=25 Gavin Kistner (Guest)
on 2006-01-05 07:29
(Received via mailing list)
On Jan 1, 2006, at 5:47 PM, Hal Fulton wrote:

> 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 :)
This topic is locked and can not be replied to.