Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > Freezing Variable Assignment

Reply
Thread Tools

Freezing Variable Assignment

 
 
Nicholas Van Weerdenburg
Guest
Posts: n/a
 
      12-06-2004
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


 
Reply With Quote
 
 
 
 
David A. Black
Guest
Posts: n/a
 
      12-06-2004
Hi --

On Mon, 6 Dec 2004, Nicholas Van Weerdenburg wrote:

> Hi,
>
> Is there a feature to freeze variable assignment?
>
> e.g.
> a="hello"
> a.assignfreeze
> a="goodbye" # ===> generates exception


I tend to think this would be a pretty radical reconceptualization of
how variable identifiers relate to objects, rather than just a
feature. At the very least it would probably have to be something
like:

freeze_identifier(:a)

as opposed to sending a message to the object referenced by 'a'. (In
your example you'd be sending the message 'assignfreeze' to the string
"hello".)

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


You'd have to define 'type' and/or 'similar object', which isn't
always easy


David

--
David A. Black
http://www.velocityreviews.com/forums/(E-Mail Removed)



 
Reply With Quote
 
 
 
 
Austin Ziegler
Guest
Posts: n/a
 
      12-06-2004
On Mon, 6 Dec 2004 11:51:55 +0900, Nicholas Van Weerdenburg
<(E-Mail Removed)> 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 <(E-Mail Removed)>
wrote:
> "Nicholas Van Weerdenburg" <(E-Mail Removed)> 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 * (E-Mail Removed)
* Alternate: (E-Mail Removed)


 
Reply With Quote
 
Joel VanderWerf
Guest
Posts: n/a
 
      12-06-2004
Austin Ziegler wrote:
> On Mon, 6 Dec 2004 11:51:55 +0900, Nicholas Van Weerdenburg
> <(E-Mail Removed)> 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.


 
Reply With Quote
 
Eric Hodel
Guest
Posts: n/a
 
      12-06-2004
On 06 Dec 2004, at 07:32, itsme213 wrote:

>
> "Austin Ziegler" <(E-Mail Removed)> 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"



 
Reply With Quote
 
Austin Ziegler
Guest
Posts: n/a
 
      12-06-2004
On Tue, 7 Dec 2004 07:12:37 +0900, itsme213 <(E-Mail Removed)> wrote:
> "Eric Hodel" <(E-Mail Removed)> 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.


You may disagree, but you'd be incorrect.

irb(main):008:0> class << a
irb(main):009:1> def matz
irb(main):010:2> "matz"
irb(main):011:2> end
irb(main):012:1> end
TypeError: can't modify frozen object
from (irb):9

(Assuming the same Effable that has been discussed to this point.)

The object referred to by 'a' is frozen, not the instance variables
of said object.

The fundamental operation is *freezing the object*.

> @a = "foo"
> self.freeze
> @a = "bar"
>
> Ruby just happens to treat local variables differently. There is
> no fundamental reason to do so.


Sure there is, and it's precisely because variables are simply
labels, but instance variables are part of the state of the object.

-austin
--
Austin Ziegler * (E-Mail Removed)
* Alternate: (E-Mail Removed)


 
Reply With Quote
 
Austin Ziegler
Guest
Posts: n/a
 
      12-06-2004
On Mon, 6 Dec 2004 14:32:12 +0900, Joel VanderWerf
<(E-Mail Removed)> wrote:
> Austin Ziegler wrote:
> > On Mon, 6 Dec 2004 11:51:55 +0900, Nicholas Van Weerdenburg
> > <(E-Mail Removed)> 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.


That makes sense, and it seems that the observable-attr is the right
thing for what he needs there.

-austin
--
Austin Ziegler * (E-Mail Removed)
* Alternate: (E-Mail Removed)


 
Reply With Quote
 
Eric Hodel
Guest
Posts: n/a
 
      12-07-2004
On 06 Dec 2004, at 14:12, itsme213 wrote:

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


variable.c disagrees with you:

VALUE
rb_ivar_set(obj, id, val)
VALUE obj;
ID id;
VALUE val;
{
if (!OBJ_TAINTED(obj) && rb_safe_level() >= 4)
rb_raise(rb_eSecurityError, "Insecure: can't modify instance
variable");
if (OBJ_FROZEN(obj)) rb_error_frozen("object");

> 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"


No, self is frozen, not @a. Your example is no different than the one
using Effable.

@a = "foo" # self.instance_variable_set "@a", "foo"
self.freeze
@b = "bar" # self.instance_variable_set "@b", "bar", raises because
self is frozen.



 
Reply With Quote
 
Jim Weirich
Guest
Posts: n/a
 
      12-07-2004
> On 06 Dec 2004, at 14:12, itsme213 wrote:
> > I respecfully but heartily disagree. Ruby freezes objects by freezing
> > their instance variables. The latter is the fundamental operation.


On Monday 06 December 2004 07:47 pm, Eric Hodel wrote:
> variable.c disagrees with you:


You guys are talking past each other ...

Itsme213: "Ruby freezes objects by freezing their instance variables"

Weirich Translation: When a Ruby object is frozen, the binding of its
instances variable names to values are made unchangeable (i.e. frozen).

Eric points to variable.c, which implements the policy annunciated by itsme.
And David correctly points out that the simple view of only looking at the
instance variables does not paint the whole picture (e.g. freezing arrays).

But as far as classes implemented in Ruby (as opposed to classes implemented
in C), the viewpoint is pretty right on.

--
-- Jim Weirich (E-Mail Removed) http://onestepback.org
-----------------------------------------------------------------
"Beware of bugs in the above code; I have only proved it correct,
not tried it." -- Donald Knuth (in a memo to Peter van Emde Boas)


 
Reply With Quote
 
David A. Black
Guest
Posts: n/a
 
      12-07-2004
Hi --

On Tue, 7 Dec 2004, Jim Weirich wrote:

> > On 06 Dec 2004, at 14:12, itsme213 wrote:
> > > I respecfully but heartily disagree. Ruby freezes objects by freezing
> > > their instance variables. The latter is the fundamental operation.

>
> On Monday 06 December 2004 07:47 pm, Eric Hodel wrote:
> > variable.c disagrees with you:

>
> You guys are talking past each other ...
>
> Itsme213: "Ruby freezes objects by freezing their instance variables"
>
> Weirich Translation: When a Ruby object is frozen, the binding of its
> instances variable names to values are made unchangeable (i.e. frozen).


David's previous statement on this: "One of the consequences of
[calling a.freeze] (though not the only consequence) is that a's
instance variables bindings are frozen."

> Eric points to variable.c, which implements the policy annunciated by itsme.
> And David correctly points out that the simple view of only looking at the
> instance variables does not paint the whole picture (e.g. freezing arrays).
>
> But as far as classes implemented in Ruby (as opposed to classes implemented
> in C), the viewpoint is pretty right on.


But that, in turn, is because Kernel#freeze freezes an object's state,
and state for non-builtins is generally (always?) a matter of instance
variables. That's why I disagree with itsme213 that instance
variables are a good model for how to treat local variables. (Not
that that matters, really; if it's a good idea to be able to freeze
local variable bindings [I'm not convinced it is], it doesn't have to
depend on analogy with Kernel#freeze.)

One could perhaps reason that a Binding "has" local variables, in
somewhat the same way that an object "has" instance variables, and
that there should be some way to freeze those bindings too (i.e., the
bindings in a Binding). The cases are not exactly parallel, though,
since a Binding can also have instance variables.... But it might be
an alternative way to approach it.


David

--
David A. Black
(E-Mail Removed)



 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
"Variable variable name" or "variable lvalue" mfglinux Python 11 09-12-2007 03:08 AM
Assignment operator self-assignment check Chris C++ 34 09-26-2006 04:26 AM
Implicit iterator variable $_ changing to ### upon variable assignment? Derek Basch Perl Misc 8 08-12-2006 06:30 PM
Augument assignment versus regular assignment nagy Python 36 07-20-2006 07:24 PM
How do I scope a variable if the variable name contains a variable? David Filmer Perl Misc 19 05-21-2004 03:55 PM



Advertisments