Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > Simulating single assignment in Ruby

Reply
Thread Tools

Simulating single assignment in Ruby

 
 
Daniel Berger
Guest
Posts: n/a
 
      05-18-2007
Hi,

Is there a way to freeze instance variables in Ruby in order to make
them single assignment? I'm just wondering if there's a way to simulate
Erlang in this regard as a way to avoid side effects.

I don't want to simply not define (or undefine) a setter method because
you could still get at the instance variable via instance_variable_set.
Redefining instance_variable_set won't work either, because that method
is apparently not called when performing direct assignment of instance
variables. I tried calling the freeze method on the instance variables
directly but that didn't seem to work either.

Is it possible?

Regards,

Dan

 
Reply With Quote
 
 
 
 
Austin Ziegler
Guest
Posts: n/a
 
      05-18-2007
On 5/17/07, Daniel Berger <(E-Mail Removed)> wrote:
> Is there a way to freeze instance variables in Ruby in order to make
> them single assignment? I'm just wondering if there's a way to
> simulate Erlang in this regard as a way to avoid side effects.
>
> I don't want to simply not define (or undefine) a setter method
> because you could still get at the instance variable via
> instance_variable_set. Redefining instance_variable_set won't work
> either, because that method is apparently not called when performing
> direct assignment of instance variables. I tried calling the freeze
> method on the instance variables directly but that didn't seem to work
> either.


Do it differently:

require 'digest/md5'

class Module
def erl_accessor(*names)
names.each do |name|
var = "@_#{Digest::MD5.hexdigest(rand(65536).to_s + name.to_s)}"
define_method(name) { || instance_variable_get(var) }
define_method("#{name}=") { |v|
instance_variables.include? var and raise "Cannot change @#{name}."
instance_variable_set(var, v)
}
end
nil
end
end

class Foo; erl_accessor :bar, :baz; end

foo = Foo.new
foo.bar = 5

Since your actual instance variables aren't related to the names, you
can only access through accessors.

-austin
--
Austin Ziegler * http://www.velocityreviews.com/forums/(E-Mail Removed) * http://www.halostatue.ca/
* (E-Mail Removed) * http://www.halostatue.ca/feed/
* (E-Mail Removed)

 
Reply With Quote
 
 
 
 
Sven Suska
Guest
Posts: n/a
 
      05-18-2007
Austin Ziegler schrieb:

> On 5/17/07, Daniel Berger <(E-Mail Removed)> wrote:
>
>> Is there a way to freeze instance variables in Ruby in order to make
>> them single assignment? I'm just wondering if there's a way to
>> simulate Erlang in this regard as a way to avoid side effects.

>
> class Module
> def erl_accessor(*names)
> [...]
> define_method("#{name}=") { |v|
> instance_variables.include? var and raise "Cannot change
> @#{name}."
> instance_variable_set(var, v)


What about Thread safety here?
I think you would have do lock before the variable is tested.
If another thread were to assign the same variable
just after the test and before the last line is executed,
then other assignment would be lost, wouldn't it?

I stumbled over this, because this issue also came up
with my proposal of a "growth-allowing freeze"-state of objects.

Regards
Sven

 
Reply With Quote
 
ara.t.howard
Guest
Posts: n/a
 
      05-19-2007

On May 17, 2007, at 6:10 PM, Daniel Berger wrote:

> Hi,
>
> Is there a way to freeze instance variables in Ruby in order to
> make them single assignment? I'm just wondering if there's a way to
> simulate Erlang in this regard as a way to avoid side effects.
>
> I don't want to simply not define (or undefine) a setter method
> because you could still get at the instance variable via
> instance_variable_set. Redefining instance_variable_set won't work
> either, because that method is apparently not called when
> performing direct assignment of instance variables. I tried calling
> the freeze method on the instance variables directly but that
> didn't seem to work either.
>
> Is it possible?
>
> Regards,
>
> Dan
>


cfp:~/src/ruby/ > cat a.rb
class Class
def fattr a, &b
define_method(a){ instance_eval &b }
end
end

class C
fattr(:a){ 40 }
fattr(:b){ a + 2 }
end

c = C.new
p c.b


cfp:~/src/ruby/ > ruby a.rb
42


with this approach there is simply no variable to modify - it exists
only through closure. i know someone could hack in some crazy
Binding.of_caller thing to munge the closure, but it would be very
painful.

kind regards.

-a
--
we can deny everything, except that we have the possibility of being
better. simply reflect on that.
h.h. the 14th dalai lama




 
Reply With Quote
 
Sven Suska
Guest
Posts: n/a
 
      05-19-2007
ara.t.howard schrieb:

> class Class
> def fattr a, &b
> define_method(a){ instance_eval &b }
> end
> end
>
> class C
> fattr(:a){ 40 }
> fattr(:b){ a + 2 }
> end
> c = C.new
> p c.b
> # => 42
> with this approach there is simply no variable to modify - it exists
> only through closure.


But a method to modify:
class C
fattr(:b){ 17 }
end
p c.b # => 17

Or did I get something wrong?

Sven

 
Reply With Quote
 
ara.t.howard
Guest
Posts: n/a
 
      05-19-2007

On May 19, 2007, at 10:46 AM, Sven Suska wrote:

> ara.t.howard schrieb:
>
>> class Class
>> def fattr a, &b
>> define_method(a){ instance_eval &b }
>> end
>> end
>>
>> class C
>> fattr(:a){ 40 }
>> fattr(:b){ a + 2 }
>> end
>> c = C.new
>> p c.b # => 42
>> with this approach there is simply no variable to modify - it
>> exists only through closure.

>
> But a method to modify:
> class C
> fattr(:b){ 17 }
> end
> p c.b # => 17
>
> Or did I get something wrong?
>
> Sven
>


yes of course. and we also have 'remove_const :C' which allows us to
replace the class wholesale, and this line of reasoning extends all
the way up in ruby. still - my approach does, in fact, prevent
modifying instance vars; the fact that the class itself can stiff be
modified (by adding methods) may or may not be an issue. perhaps
enclosed attributes and C.freeze and (class << C;self;end).freeze
would be sufficient.

-a
--
we can deny everything, except that we have the possibility of being
better. simply reflect on that.
h.h. the 14th dalai lama




 
Reply With Quote
 
Daniel Berger
Guest
Posts: n/a
 
      05-21-2007
ara.t.howard wrote:
>
> On May 17, 2007, at 6:10 PM, Daniel Berger wrote:
>
>> Hi,
>>
>> Is there a way to freeze instance variables in Ruby in order to make
>> them single assignment? I'm just wondering if there's a way to
>> simulate Erlang in this regard as a way to avoid side effects.
>>
>> I don't want to simply not define (or undefine) a setter method
>> because you could still get at the instance variable via
>> instance_variable_set. Redefining instance_variable_set won't work
>> either, because that method is apparently not called when performing
>> direct assignment of instance variables. I tried calling the freeze
>> method on the instance variables directly but that didn't seem to work
>> either.
>>
>> Is it possible?
>>
>> Regards,
>>
>> Dan
>>

>
> cfp:~/src/ruby/ > cat a.rb
> class Class
> def fattr a, &b
> define_method(a){ instance_eval &b }
> end
> end
>
> class C
> fattr(:a){ 40 }
> fattr(:b){ a + 2 }
> end
>
> c = C.new
> p c.b
>
>
> cfp:~/src/ruby/ > ruby a.rb
> 42
>
>
> with this approach there is simply no variable to modify - it exists
> only through closure. i know someone could hack in some crazy
> Binding.of_caller thing to munge the closure, but it would be very painful.
>
> kind regards.


Ara, Austin - thanks for the respsonses. Both are interesting approaches.

However, I think I'm going to try digging into the opaque objects behind
the scenes via DL and see if I can't do something more directly. Perhaps
I'll contribute that back to evil.rb.

Regards,

Dan

 
Reply With Quote
 
Paul Brannan
Guest
Posts: n/a
 
      05-23-2007
I think what you want is a constant:

class Foo
def initialize
sc.const_set(:FOO, 42)
end

def foo
puts sc::FOO
end

def sc
class << self; self; end
end
end

Foo.new.foo #=> 42

(I wish it were possible to use just FOO instead of sc::FOO, but
constant lookup in ruby is static).

I like Ara's method too. I wouldn't have considered it.

Paul


 
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
Tied hash: Differentiating between assignment of single value andentire hash bernd Perl Misc 0 04-24-2012 02:41 PM
precedence of single-line rescue and assignment matt neuburg Ruby 7 05-08-2008 04:37 AM
Assignment operator self-assignment check Chris C++ 34 09-26-2006 04:26 AM
Augument assignment versus regular assignment nagy Python 36 07-20-2006 07:24 PM
Combine hash declaration/assignment into single statement? usenet@DavidFilmer.com Perl Misc 34 03-08-2006 03:09 AM



Advertisments