Планировщик Руфуса в Синатре

Я использую планировщик Rufus в приложении Sinatra. Могу ли я получить доступ к вспомогательным методам из блока "scheduler do"? Мне не удалось это сделать (я получаю "неопределенный метод`check'для ошибки main:Object"), поэтому теперь я должен определить метод внутри блока helpers (чтобы использовать его также в блоке"post '/' do")), а затем скопируйте тело метода в блок планировщика. Это не имеет смысла:(Есть ли способ избежать повторения? Могу ли я определить метод где-нибудь еще и вызвать его в планировщике?

2 ответа

Решение

Это зависит от того, где используется ваш планировщик. Блок будет иметь доступ к локальному контексту, поэтому, если вы используете его где-то, у вас есть доступ к помощнику, то он также должен иметь доступ к помощнику.

Взятые частично из документов

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

Сказав это, у вас не будет доступа к scheduler вот так вот:

configure do
  set :scheduler, { Rufus::Scheduler.start_new }
end

и тогда вы можете сделать

  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

или вы можете поместить его в переменную экземпляра класса модуля:

module MyScheduler
  def self.scheduler
    @scheduler ||= Rufus::Scheduler.start_new
  end
end

тогда вы можете получить доступ к планировщику везде через:

MyScheduler.scheduler

но my_helper будет по-прежнему доступен только в объеме запроса. Если вы хотите получить доступ к методу в качестве помощника и выйти за пределы области запроса, то извлеките его так, как подразумевает jmettraux для:

module MyHelpers
  def self.my_helper
    # do something
  end
end

в Синатре:

helpers
  def my_helper
    MyHelpers.my_helper
  end
end

тогда можно сделать:

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

Все очень замысловато! Вы можете смешивать и сочетать и найти то, что работает для ваших нужд.

Я смотрел на http://japhr.blogspot.jp/2009/03/sinatra-innards-deletgator.html

Вы могли бы сделать что-то вроде:

# 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
Другие вопросы по тегам