web-dev-qa-db-ja.com

rakeタスクのdefブロック

undefined local variable or method 'address_geo' for main:Object次のrakeタスクを使用します。それの何が問題なのですか?

include Geokit::Geocoders

namespace :geocode do
  desc "Geocode to get latitude, longitude and address"
  task :all => :environment do
    @spot = Spot.find(:first)
    if @spot.latitude.blank? && [email protected]?
      puts address_geo
    end

    def address_geo
      arr = []
      arr << address if @spot.address
      arr << city if @spot.city
      arr << country if @spot.country
      arr.reject{|y|y==""}.join(", ")
    end
  end
end
41
Victor

Rakeタスク内でメソッドを定義しています。関数を取得するには、rakeタスクの外側(タスクブロックの外側)を定義する必要があります。これを試して:

include Geokit::Geocoders

namespace :geocode do
  desc "Geocode to get latitude, longitude and address"
  task :all => :environment do
    @spot = Spot.find(:first)
    if @spot.latitude.blank? && [email protected]?
      puts address_geo
    end
  end

  def address_geo
    arr = []
    arr << address if @spot.address
    arr << city if @spot.city
    arr << country if @spot.country
    arr.reject{|y|y==""}.join(", ")
  end
end
98
rubyprince

注意:rakeファイルで定義されたメソッドは、最終的にグローバル名前空間で定義されます。

メソッドをモジュールまたはクラスに抽出することを提案します。これは、rakeファイルで定義されたメソッドが最終的にグローバル名前空間で定義されるためです。つまり、それらは、rakeファイル内だけでなく、どこからでも呼び出すことができます(名前空間が指定されている場合でも!)。

これは、2つの異なるRakeタスクに同じ名前の2つのメソッドがある場合、知らないうちにそのうちの1つが上書きされることも意味します。非常に致命的です。

すばらしい説明はここにあります: https://kevinjalbert.com/defined_methods-in-rake-tasks-you-re-gonna-have-a-bad-time/

25
Hula_Zell