The Artima Developer Community
Sponsored Link

Ruby Buzz Forum
Scope Kills

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Matt Williams

Posts: 466
Nickname: aetherical
Registered: Feb, 2008

Matt Williams is a jack-of-all trades living in Columbus, OH.
Scope Kills Posted: May 14, 2008 1:01 PM
Reply to this message Reply

This post originated from an RSS feed registered with Ruby Buzz by Matt Williams.
Original Post: Scope Kills
Feed Title: Ruby Blender
Feed URL: http://feeds2.feedburner.com/RubyBlender
Feed Description: This blog contains short-ish ruby tips, hints, and techniques.
Latest Ruby Buzz Posts
Latest Ruby Buzz Posts by Matt Williams
Latest Posts From Ruby Blender

Advertisement
I'm not talking about bad breath. Rather, I'm talking about scope in ruby.

First off, I'm not talking about bad breath. Rather, I'm talking about scope in ruby.

The previous entry, attributes with default values (on steroids), had an issue with it, due to the way in which ruby defines scope (as of 1.8, scope is supposed to change in 1.9). Here's the "broken" code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

class Object
  def self.attribute(*arg,&block)
    (name,value) = arg
    self.send(:define_method, name) {
      if instance_variables.include? "@#{name}"
           self.instance_eval "@#{name}"
      else
        if block_given?
          instance_eval &block
        else
          value
        end
      end
    }
    self.send(:define_method, "#{name}="){ |value|
      self.instance_eval "@#{name} = value"
    }
  end
end

The problem is with the value variable. Because it is set within the Object#attribute method, the reference to value is the same throughout the entire method. So, when we change value, by setting it in the "setter" method, we are changing it for every instance of the variable. In addition, since we're setting it at the class level, any object which belongs to the class for which we are setting it has the same value. The solution is pretty simple:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

def self.attribute(*arg,&block)
    (name, default) = arg
    self.send(:define_method, name) {
      if instance_variables.include? "@#{name}"
           self.instance_eval "@#{name}"
      else
        if block_given?
          instance_eval &block
        else
          default
        end
      end
    }
    self.send(:define_method, "#{name}="){ |value|
      self.instance_eval "@#{name} = value"
    }
  end
end

Notice that I'm using default now within the accessor method. This removes the issue with value, and it now works properly.

Read: Scope Kills

Topic: Testing: Duplicate Code in Your Tests Previous Topic   Next Topic Topic: mod_rails and

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use