Ah, this is a subtle one. You're running into an aspect of how Ruby deals with local variables. What you want is to use set(), instead of assignment, since variables in capistrano are not really Ruby variables. Try this:

  if tier.nil?
    set :tier, "sandbox"
  end

That should do the trick. Now, if you're curious about the behavior you saw, read on:

First, a simple example. Suppose you have the following Ruby script:

  p x

If you execute that command, you'll get an exception, "undefined local variable or method `x'". However, if you do something like this:

  if false
    x = "hello"
  end

  p x

You'll now get the output 'nil'. Even though x is never explicitly set! This is because Ruby will silently vivify x, due to its reference in the body of the if.

Now, Capistrano handles variables specially. It actually keeps a hash of key/value pairs, and uses method_missing to hook into that. Thus, your capistrano script can say:

 p tier

and have it just work, even though you do not explicitly set tier as a local variable. So, let's look at your example:

  p tier #-> gives 'dev'

  if tier.nil?  #-> this is false
    tier = 'sandbox'
  end

  p tier #-> gives 'null'

The first line works in capistrano, not because tier is a local variable, but because of method_missing. The local variable is not actually defined, so method_missing gets called, which looks up the variable and returns the value.

Ditto for the condition in the if clause.

However, you are setting a local variable in the body of the if, which causes ruby to implicitly vivify 'tier' as a local variable, with a value of nil. The next time you ask for 'tier', that local variable is used, and method_missing does not get called.

Hope that makes sense,

Jamis

On Nov 2, 2006, at 9:12 AM, [EMAIL PROTECTED] wrote:


I am trying to write my deploy script that will work for multiple
deployment environments (sandbox, dev, staging, production).  While
working on this I ran into a problem with variable assignment. I wrote
some debug scripts to check on somethings and got the strangest
results.  Here is what I wrote in my deploy.rb:

puts "tier: #{tier}" if !tier.nil?
puts tier.nil?.to_s
puts "tier: #{tier}" if !tier.nil?
puts tier.nil?.to_s
if tier.nil?
  tier = 'sandbox'
end
puts "tier: #{tier}"
#puts "ENV[]: " + ENV["TIER"] if !ENV["TIER"]
raise "stop"

I then run the following command from my command line:
cap -S tier=dev deploy

This is what is outputted to my console:
C:\Ruby\InstantRails\rails_apps\video_content_manager>cap -S tier=dev
deploy
    loading configuration
C:/Ruby/InstantRails/ruby/lib/ruby/gems/1.8/gems/capis
trano-1.2.0/lib/capistrano/recipes/standard.rb
    loading configuration ./config/deploy.rb
    loading configuration
C:/Ruby/InstantRails/ruby/lib/ruby/gems/1.8/gems/mongr
el_cluster-0.2.0/lib/mongrel_cluster/recipes.rb
tier: dev
false
tier: dev
false
tier:
./config/deploy.rb:35:in `load': stop (RuntimeError)
        from
C:/Ruby/InstantRails/ruby/lib/ruby/gems/1.8/gems/capistrano-1.2.0/l
ib/capistrano/configuration.rb:146:in `load'
        from
C:/Ruby/InstantRails/ruby/lib/ruby/gems/1.8/gems/capistrano-1.2.0/l
ib/capistrano/configuration.rb:125:in `load'
        from
C:/Ruby/InstantRails/ruby/lib/ruby/gems/1.8/gems/capistrano-1.2.0/l
ib/capistrano/configuration.rb:125:in `load'
        from
C:/Ruby/InstantRails/ruby/lib/ruby/gems/1.8/gems/capistrano-1.2.0/l
ib/capistrano/cli.rb:252:in `execute_recipes!'
        from
C:/Ruby/InstantRails/ruby/lib/ruby/gems/1.8/gems/capistrano-1.2.0/l
ib/capistrano/cli.rb:252:in `execute_recipes!'
        from
C:/Ruby/InstantRails/ruby/lib/ruby/gems/1.8/gems/capistrano-1.2.0/l
ib/capistrano/cli.rb:233:in `execute!'
        from
C:/Ruby/InstantRails/ruby/lib/ruby/gems/1.8/gems/capistrano-1.2.0/l
ib/capistrano/cli.rb:12:in `execute!'
        from
C:/Ruby/InstantRails/ruby/lib/ruby/gems/1.8/gems/capistrano-1.2.0/b
in/cap:11
        from C:/Ruby/InstantRails/ruby/bin/cap:18

As you can see on the last line before the exception is thrown the
variable tier suddenly goes to nil.  If I then comment out the
following line:

if tier.nil?
#  tier = 'sandbox'
end

I get the following output:

C:\Ruby\InstantRails\rails_apps\video_content_manager>cap -S tier=dev
deploy
    loading configuration
C:/Ruby/InstantRails/ruby/lib/ruby/gems/1.8/gems/capis
trano-1.2.0/lib/capistrano/recipes/standard.rb
    loading configuration ./config/deploy.rb
    loading configuration
C:/Ruby/InstantRails/ruby/lib/ruby/gems/1.8/gems/mongr
el_cluster-0.2.0/lib/mongrel_cluster/recipes.rb
tier: dev
false
tier: dev
false
tier: dev
./config/deploy.rb:35:in `load': stop (RuntimeError)
        from
C:/Ruby/InstantRails/ruby/lib/ruby/gems/1.8/gems/capistrano-1.2.0/l
ib/capistrano/configuration.rb:146:in `load'
        from
C:/Ruby/InstantRails/ruby/lib/ruby/gems/1.8/gems/capistrano-1.2.0/l
ib/capistrano/configuration.rb:125:in `load'
        from
C:/Ruby/InstantRails/ruby/lib/ruby/gems/1.8/gems/capistrano-1.2.0/l
ib/capistrano/configuration.rb:125:in `load'
        from
C:/Ruby/InstantRails/ruby/lib/ruby/gems/1.8/gems/capistrano-1.2.0/l
ib/capistrano/cli.rb:252:in `execute_recipes!'
        from
C:/Ruby/InstantRails/ruby/lib/ruby/gems/1.8/gems/capistrano-1.2.0/l
ib/capistrano/cli.rb:252:in `execute_recipes!'
        from
C:/Ruby/InstantRails/ruby/lib/ruby/gems/1.8/gems/capistrano-1.2.0/l
ib/capistrano/cli.rb:233:in `execute!'
        from
C:/Ruby/InstantRails/ruby/lib/ruby/gems/1.8/gems/capistrano-1.2.0/l
ib/capistrano/cli.rb:12:in `execute!'
        from
C:/Ruby/InstantRails/ruby/lib/ruby/gems/1.8/gems/capistrano-1.2.0/b
in/cap:11
        from C:/Ruby/InstantRails/ruby/bin/cap:18

The problem has disappeared.  It seems like capistrano is doing
something weird for an assignment to a local variable that it should
not even be executing.  Please Help!?!?!?


--~--~---------~--~----~------------~-------~--~----~
To unsubscribe from this group, send email to capistrano- [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/ group/capistrano
-~----------~----~----~----~------~----~------~--~---


Attachment: smime.p7s
Description: S/MIME cryptographic signature

Reply via email to