rake task variable
13,242
Solution 1
Try this:
namespace :db do
server_name='myserver'
task :first_task => :environment do
connect_to(server_name)
end
task :second_task => :environment do
do_something_with(server_name)
end
end
Namespaces have access to variables declared before their scope.
Solution 2
I'd like to build on David Sulc's answer, but I recommend using an instance variable instead:
namespace :db do
@server_name = 'myserver'
task first_task: :environment do
connect_to @server_name
end
task second_task: :environment do
do_something_with @server_name
end
end
The advantage here is that later code can modify @server_name
-- something you can't do with a local variable:
namespace :db do
@server_name = 'server_2'
end
Comments
-
Mellon almost 2 years
I have two Rake tasks under the same namespace like following:
namespace :db do task :first_task => :environment do server_name='myserver' connect_to(server_name) end task :second_task => :environment do server_name='myserver' do_something_with(server_name) end end
As you see, both tasks are under the same namespace and both tasks use
server_name='myserver'
constant variable.It really looks ugly to define the
server_name
variable twice under the same namespace, how can I have one place defining this variable so both tasks can use it? -
meandre over 9 yearsNo, you shouldn't do that. The reason is that you don't know, where that ivar goes to. Neither do I. A rake task is declared using a block, not a class, and therefore the context of the ivar is unclear.
-
David J. over 9 years@meandre What is the problem with using an instance variable in this way? Can you demonstrate where it could go wrong? Do you have a better suggestion? See the section "Instance Variables in Tasks" in daneharrigan.com/2010/06/rake-tasks-102 for more detailed discussion.
-
David J. over 9 years@meandre Actually, instance variables defined in the way I show get evaluated in the context of
Rake.application.in_namespace(name, &block)
(see github.com/jimweirich/rake/blob/v10.3.2/lib/rake/…). I'm not sure what your concern is. -
meandre over 9 yearsInstance variables are evaluated in some object's context (not in a context of a method like
in_namespace()
. A block/Proc
in Ruby gets bound to an object at the moment the block is declared (not whencall
ed/yield
ed - except forinstance_eval
and someUnboundMethod#bind
magic you don't want to know about). As I see,TaskManager#in_namespace
makes no use ofinstance_eval
thus leading to sharing all instance variables among allrake
tasks. If that mess works for you, it's ok for you, but that's definitely not a better way. -
David J. over 9 years@meandre Thanks for digging in and explaining. Having an instance variable shared across all rake tasks is indeed global state at its 'finest'. Would you suggest an alternative way of parameterizing the rake tasks such as
server_name
as my example showed? (That example is one reason why I suggested this approach, but I'm certainly open to better ways.) -
knut almost 3 yearsBut get attention, if you define
server_name
before you define the namespace. Then the variable can be modified outside the namespace definition. See also stackoverflow.com/questions/30328197