[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

Freezing Variable Assignment

Nicholas Van Weerdenburg

12/6/2004 2:52:00 AM

Hi,

Is there a feature to freeze variable assignment?

e.g.
a="hello"
a.assignfreeze
a="goodbye" # ===> generates exception

Or, in a related vein, a type freeze, so that only similar objects can be added.

I realize that constants offer assignment freezing to a certain degree.

The reason I ask, is that I stepped over-top of some framework
variables today, and it was hard to find out what was going on. Where
as ruby protects keywords, it would be nice if frameworks or custom
domain specific languages could do the same.

Thanks,
Nick


61 Answers

Its Me

12/6/2004 3:18:00 AM

0


"Nicholas Van Weerdenburg" <vanweerd@gmail.com> wrote in message
> Is there a feature to freeze variable assignment?
>
> e.g.
> a="hello"
> a.assignfreeze
> a="goodbye" # ===> generates exception

I like this, specially if it also covers instance variables. I think Ruby's
current freeze is a special case, in which all instance variables of the
given object are frozen.

It's in the same vein that I think Observable should target a instance
variable (an attribute, more generally) of an object, rather than an entire
object.


dblack

12/6/2004 4:12:00 AM

0

Austin Ziegler

12/6/2004 4:33:00 AM

0

On Mon, 6 Dec 2004 11:51:55 +0900, Nicholas Van Weerdenburg
<vanweerd@gmail.com> wrote:
> Is there a feature to freeze variable assignment?
>
> e.g.
> a="hello"
> a.assignfreeze
> a="goodbye" # ===> generates exception

No, but you might be able to do something with WeakRef (weakref.rb)
or some other proxy class and freezing that.

class Var
def initialize(value)
@value = value
@const = false
end

def const!
@const = true
end

def const?
@const
end

attr_accessor :value
def value=(value)
raise "Var #{@value.inspect} is constant." if const?
@value = value
end

def class
@value.class
end

def id
@value.__id__
end

def method_missing(sym, *args)
@value.send(sym, *args)
end

def inspect
@value.inspect
end
end

a = Var.new("hello")
a.value = "goodbye"
a.class
a.const!
a.value = "yo!"

> Or, in a related vein, a type freeze, so that only similar objects
> can be added.

Define "similar objects". What if I want a variable to be only an
IO? Should I restrict it to items which inherit from IO? If so, I
lose the ability to transparently use StringIO or ZLib::GzipWriter
(or GzipReader) objects. This gets to the heart of why static typing
is generally a bad idea -- it makes classes less extensible, and
when you have static typing enforced by the language, there's almost
always ways to escape out of it with no protection from the compiler
involved (e.g., pointers).

> I realize that constants offer assignment freezing to a certain
> degree.
>
> The reason I ask, is that I stepped over-top of some framework
> variables today, and it was hard to find out what was going on.
> Where as ruby protects keywords, it would be nice if frameworks or
> custom domain specific languages could do the same.

What do you mean, specifically? Did you reopen the classes in the
framework, or something? If the framework put variables in such a
way as to make it easy for you to overwrite something that shouldn't
have been, then I think that it's a bug in the framework, not in
your code. In some ways, Transaction::Simple is a framework, and I
have deliberately made it "hard" to step on Transaction::Simple
variables.

On Mon, 6 Dec 2004 12:22:35 +0900, itsme213 <itsme213@hotmail.com>
wrote:
> "Nicholas Van Weerdenburg" <vanweerd@gmail.com> wrote in message
>> Is there a feature to freeze variable assignment?
>>
>> e.g.
>> a="hello"
>> a.assignfreeze
>> a="goodbye" # ===> generates exception
> I like this, specially if it also covers instance variables. I
> think Ruby's current freeze is a special case, in which all
> instance variables of the given object are frozen.

Um. Not really. Only the direct replacement of those objects is
frozen.

a = Struct.new("Effable", :a, :b).new
a.a = "abcdef"
a.b = %w(a b c d e f)
a.freeze
a.a = "ghijkl" # raises error
a.a.gsub!(/a/, 'z') # no error
a.b[0] = 'z' # no error

Freeze isn't necessarily recursive.

> It's in the same vein that I think Observable should target a
> instance variable (an attribute, more generally) of an object,
> rather than an entire object.

Why?

-austin
--
Austin Ziegler * halostatue@gmail.com
* Alternate: austin@halostatue.ca


Joel VanderWerf

12/6/2004 5:32:00 AM

0

Austin Ziegler wrote:
> On Mon, 6 Dec 2004 11:51:55 +0900, Nicholas Van Weerdenburg
> <vanweerd@gmail.com> wrote:
...
>>It's in the same vein that I think Observable should target a
>>instance variable (an attribute, more generally) of an object,
>>rather than an entire object.
>
>
> Why?

It's useful in GUI code, where each control, field, etc. is wired up to
one or more attrs in the window instance, and other related windows can
be wired up to those attrs too, to keep their state synchronized. See,
for instance, foxtails on raa, which uses FXRuby and observable (also on
raa). That observable lib (which should have been called
observable-attr) is just what Nicholas described: it makes attrs observable.


Its Me

12/6/2004 2:40:00 PM

0

> >>It's in the same vein that I think Observable should target a
> >>instance variable (an attribute, more generally) of an object,
> >>rather than an entire object.
> >
> >
> > Why?
>
> It's useful in GUI code, where each control, field, etc. is wired up to
> one or more attrs in the window instance, and other related windows can
> be wired up to those attrs too, to keep their state synchronized. See,
> for instance, foxtails on raa, which uses FXRuby and observable (also on
> raa). That observable lib (which should have been called
> observable-attr) is just what Nicholas described: it makes attrs
observable.

GUIs are a good example, including wiring up attributes of controls (e.g.
theTemperatureIndicator.color) to attributes of domain objects (e.g.
theFurnace.temperature).

I'd go further and say that almost any place one registers interest in an
object, what is really intended is an interest in some attribute (or,
equivalently, some set of attributes) of that object.

Which is why I think the freeze proposal is a Good Thing.



Its Me

12/6/2004 3:30:00 PM

0


"Austin Ziegler" <halostatue@gmail.com> wrote in message
> a = Struct.new("Effable", :a, :b).new
> a.a = "abcdef"
> a.b = %w(a b c d e f)
> a.freeze
> a.a = "ghijkl" # raises error
> a.a.gsub!(/a/, 'z') # no error
> a.b[0] = 'z' # no error
>
> Freeze isn't necessarily recursive.

Correct. All instance variables of the object are frozen, not the objects
they refer to.

One of the nice things about a pure oo language like Ruby or Smalltalk is
the clean model of state as an object graph: a set of objects and their
links via instance variables. The only possible changes of state are (a)
changes to links via deleting links or creating links (b) creation of new
objects. Freezing then is about prohibiting certain link changes.


Eric Hodel

12/6/2004 8:05:00 PM

0

On 06 Dec 2004, at 07:32, itsme213 wrote:

>
> "Austin Ziegler" <halostatue@gmail.com> wrote in message
>> a = Struct.new("Effable", :a, :b).new
>> a.a = "abcdef"
>> a.b = %w(a b c d e f)
>> a.freeze
>> a.a = "ghijkl" # raises error
>> a.a.gsub!(/a/, 'z') # no error
>> a.b[0] = 'z' # no error
>>
>> Freeze isn't necessarily recursive.
>
> Correct. All instance variables of the object are frozen, not the
> objects
> they refer to.

No, the instance variables are not frozen, the instance 'a' of Effable
is.

#a= modifies a, which is disallowed because a is frozen.

You cannot freeze variables, just objects.

a = "foo"
a.freeze
a = "bar"



Its Me

12/6/2004 10:09:00 PM

0


"Eric Hodel" <drbrain@segment7.net> wrote
> > Correct. All instance variables of the object are frozen, not the
> > objects
> > they refer to.
>
> No, the instance variables are not frozen, the instance 'a' of Effable
> is.
>
> #a= modifies a, which is disallowed because a is frozen.
>
> You cannot freeze variables, just objects.
>
> a = "foo"
> a.freeze
> a = "bar"

I respecfully but heartily disagree. Ruby freezes objects by freezing their
instance variables. The latter is the fundamental operation.

a = "foo" # makes the variable a refer to the object "foo"

a.freeze # makes the instance variables of the object "foo" frozen.

Try this:

@a = "foo"
self.freeze
@a = "bar"

Ruby just happens to treat local variables differently. There is no
fundamental reason to do so.


Its Me

12/6/2004 10:14:00 PM

0


"Eric Hodel" <drbrain@segment7.net> wrote
> > "Austin Ziegler" <halostatue@gmail.com> wrote in message
> >> a = Struct.new("Effable", :a, :b).new
> >> a.a = "abcdef"
> >> a.b = %w(a b c d e f)
> >> a.freeze
> No, the instance variables are not frozen, the instance 'a' of Effable
> is.

But 'a' is not an instance of anything. 'a' is a _variable_, it _refers_ to
an instance of Effable. The variable is not the object.


dblack

12/6/2004 10:37:00 PM

0