I'm using Rufus scheduler in a Sinatra app. Can I access helper methods from within "scheduler do" block? I didn't manage to do it (I get an "undefined method `check' for main:Object" error) so now I have to define the method inside helpers block (to use it in "post '/' do" block also) and then copy the method's body to scheduler block. It does not make sense:( Is there a way to avoid repetition? Can I define a method somewhere else and call it in scheduler?
2 Answers
It depends where your scheduler is being used. A block will have access to the context local to it, so if you're using it somewhere you have access to a helper, then it should also have access to the helper.
Taken in part from the docs
class MyApp < Sinatra::Base
# Hey, I'm in the application scope!
helpers do
def my_helper
end
end
configure do
scheduler.every('20s') do
# my_helper is ***not*** accessible here
end
end
get '/define_route/:name' do
# Request scope for '/define_route/:name'
scheduler.every('20s') do
my_helper
# my_helper is accessible here
end
end
end
Having said that, you wouldn't have access to the scheduler
like that, so:
configure do
set :scheduler, { Rufus::Scheduler.start_new }
end
and then you can do
get '/define_route/:name' do
# Request scope for '/define_route/:name'
settings.scheduler.every('20s') do
my_helper
# my_helper is accessible here
end
end
or you could put it in a module's class instance variable:
module MyScheduler
def self.scheduler
@scheduler ||= Rufus::Scheduler.start_new
end
end
then you can access the scheduler everywhere via:
MyScheduler.scheduler
but the my_helper
would still only be accessible in the request scope. If you wanted to access a method as a helper and outside the request scope, then extract it as jmettraux implied to:
module MyHelpers
def self.my_helper
# do something
end
end
in Sinatra:
helpers
def my_helper
MyHelpers.my_helper
end
end
then can do:
configure do
scheduler = Rufus::Scheduler.start_new
set :scheduler, scheduler
scheduler.every('20s') do
MyHelpers.my_helper
# my_helper is not accessible here
# but the MyHelpers.my_helper is, because it's accessible everywhere
end
end
# and/or
get "another-route" do
setting.scheduler.every('20s') do
my_helper
# my_helper is accessible here
end
end
All very convoluted! You can mix and match and find what works for your needs.

- 12,003
- 9
- 51
- 107
I was looking at http://japhr.blogspot.jp/2009/03/sinatra-innards-deletgator.html
You could probably do something like:
# in a.rb
module A
class << self; include A; end
def nada
puts "nada"
end
end
# in another file...
require 'sinatra'
helpers do
include A
end
scheduler.every('20s') do
A.nada
end

- 3,511
- 3
- 31
- 30
-
You don't need to use `include`, you can just write `helpers A` or `helpers Namespace::To::My::Special::Module` – ian Jan 31 '13 at 15:37
-
…and just to say, it should be `nada` not `A.nada` as `helpers` includes the instance methods of a module, and `nada` is not a class method. If you were going to use `A.nada` just define it in your module as `self.nada`, there'd be no need to add it to the helpers. – ian Jan 31 '13 at 15:43
-
1Thanks @iain, my solution was indeed not standing on its own. I had forgotten the "class << self; include A; end". Thanks for the "helpers Module", I didn't know Sinatra could do that. – jmettraux Jan 31 '13 at 21:26