Skip to content

Ruby Blender

  • Blog
  • About
  • Archives
  • Log in
 
Less
More
Trim
Untrim
« Older
Home
Loading
Newer »
Tag Archive for 'scope'
19Aug09 Ruby Bindings and Scope
ruby
1 Comment

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3643

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3643

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3651

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3651

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3654

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3654

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 1925

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 1925

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 2290

Warning: implode() [function.implode]: Argument must be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3242

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3265

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3265

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3306

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3357

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3357

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3502

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3502

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3643

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3643

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3651

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3651

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3654

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3654

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 1925

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 1925

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 2290

Warning: implode() [function.implode]: Argument must be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3242

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3265

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3265

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3306

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3357

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3357

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3502

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3502

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3643

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3643

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3651

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3651

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3654

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3654

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 1925

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 1925

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 2290

Warning: implode() [function.implode]: Argument must be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3242

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3265

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3265

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3306

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3357

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3357

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3502

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3502

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3643

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3643

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3651

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3651

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3654

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3654

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 1925

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 1925

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 2290

Warning: implode() [function.implode]: Argument must be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3242

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3265

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3265

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3306

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3357

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3357

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3502

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3502

One of the features of Ruby’s Kernel module (which is imported into Object, so it’s available in every class) is the binding.  The binding allows you to keep a pointer to the scope at a particular location in your application and then later evaluate code from that location.

For example (and this came up as the result of a question on the ruby talk  mailing list), one of the things you can do is obtain a list of the local variables of a method:

  |  copy code |? 
1
def my_vars(a)
2
  b=a
3
  c=b+a
4
  puts local_variables
5
end

 

returns the three variables, a, b, and c.  That’s fine, we’re still within the scope of the method.  But how about outside of our method?  This is where #binding and the Binding class come into play:

  |  copy code |? 
1
def outside(b)
2
  puts eval("local_variables", b)
3
end
4
 
5
def my_vars(a)
6
  b=a
7
  c=b+a
8
  outside(binding)
9
end

 

One thing to note: in order to work with the binding, we have to #eval code within its scope.  Thus the call to #eval with the method we are invoking and the binding.  This leads to the question from the mailing list:

we already have #has_block? to see if a block was passed. So how about
a #has_arguments? to query if _any_ arguments have been passed — Intransition

So how would we go about writing a #has_arguments? — here is a first stab:

  |  copy code |? 
01
class Object
02
  def has_arguments?(b)
03
    vars = eval("local_variables",b)
04
    return false if vars.length == 0
05
    vars.each do |v|
06
      return false if eval("#{v}.nil?",b) 
07
    end
08
    return true
09
  end
10
end
11
 
12
class Foo
13
  def initialize(first=nil)
14
    if (has_arguments? binding)
15
      puts "We're defined"
16
    else
17
      puts "Not!"
18
    end
19
  end
20
end

The only real drawback here is that we’ve got to pass in the binding itself.  Let’s try again:

  |  copy code |? 
01
class Object
02
  def has_arguments?(&b)
03
    vars = eval("local_variables",b.binding)
04
    return false if vars.length == 0
05
    vars.each do |v|
06
      return false if eval("#{v}.nil?",b) 
07
    end
08
    return true
09
  end
10
end
11
 
12
class Foo
13
  def initialize(first=nil)
14
    if (has_arguments? {}) # note the empty block
15
      puts "We're defined"
16
    else
17
      puts "Not!"
18
    end
19
  end
20
end

In this case, instead of explicitly calling #binding, we’re passing in an empty block — the block has it’s own scope, but it happens to contain the scope of then enclosing method.  It’s still not perfect, however:

  1. You need to pass in an empty block.
  2. It fails if you have local variables other than those passed in as arguments. (Pointed out by Joel VanderWerf)

Ok, it’s got some serious flaws (Charles Nutter posted a different way of solving the problem, which does work for all cases, and doesn’t use #binding).  But it does give an idea of what you can do with #binding.

Enhanced by Zemanta
 
Browse Archives ยป
  • administrivia (2)
  • configuration (1)
  • metaprogramming (1)
  • mini-saga (5)
  • programming (10)
  • rails (1)
  • ruby (15)
  • rubygems (2)
  • Uncategorized (1)
 

Recent Posts

  • Default values for Attributes
  • Arguments with Trollop
  • Database Paranoia — ActiveRecord Callbacks
  • Ruby Bindings and Scope
  • What’s #method_missing missing?

Search

Browse by Category

  • administrivia (2)
  • configuration (1)
  • metaprogramming (1)
  • mini-saga (5)
  • programming (10)
  • rails (1)
  • ruby (15)
  • rubygems (2)
  • Uncategorized (1)

Browse by Tag

  • ActiveRecord
  • binding
  • Command-line interface
  • gotcha
  • irb
  • irbc
  • Languages
  • Library
  • Local variable
  • metaprogramming
  • mini-saga
  • paradigm
  • philosophy
  • programming
  • rails
  • Recursion
  • ruby
  • rubygems
  • Ruby on Rails
  • scope
  • utilities

Browse by Month

  • September 2009 (1)
  • August 2009 (4)
  • April 2009 (1)
  • February 2009 (11)
 
 
  • Blog
  • About
  • Archives
  • Log in
 


Theme Design by Jay Kwong | Powered by WordPress and K2

 

Home Top Archives Entries FeedComments Feed