在Ruby中,如何引用模块中定义的lambda?

时间:2015-01-09 12:23:26

标签: ruby module lambda

此代码过去一直有效,直到我将lambda函数放入模块中。

这是lambda函数:

module GalleryGenerator
  @add_links_to_descriptions = lambda do |mutable_viewable_content|
    mutable_viewable_content.description = add_links_to_sources(mutable_viewable_content.description)
    return mutable_viewable_content
  end
  #...
end

以下是它的使用方法:

include GalleryGenerator

gallery = ViewableGallery.new(gallery_config.title, gallery_config.description, gallery_config.slug, \
gallery_config.sources, gallery_config.upload_date, gallery_config.map_url, gallery_config.map_title, \
gallery_config.year, viewable_photos).
update_using( \
    add_tabs_before_every_description_line(2), \
    @add_links_to_descriptions)

这就是错误:

/home/mike/Development/Projects/FT/gallery_generator/lib/gallery_generator/viewable_gallery.rb:26:in `block in update_using': undefined method `call' for nil:NilClass (NoMethodError)
from /home/mike/Development/Projects/FT/gallery_generator/lib/gallery_generator/viewable_gallery.rb:25:in `each'
from /home/mike/Development/Projects/FT/gallery_generator/lib/gallery_generator/viewable_gallery.rb:25:in `update_using'
from bin/gallery_generator:32:in `<main>'

如果lambda消息不在模块中,则一切正常。我怀疑它正在寻找错误位置的@add_links_to_descriptions现在在模块中......

我该如何解决这个问题?谢谢!

3 个答案:

答案 0 :(得分:3)

在Ruby中,名称以@ sigil开头的变量是实例变量,即属于特定对象的变量(或实例)。

在这种情况下,实例变量@add_links_to_descriptions属于常量GalleryGenerator引用的对象,并且只能由它访问,而不能访问其他对象。

Ruby中其他对象可以访问的唯一内容是方法。因此,您需要定义一个返回实例变量值的方法。这种方法在Ruby中称为属性读取器,有一种方便的方法可以自动生成它们,称为Module#attr_reader

class << GalleryGenerator
  attr_reader :add_links_to_descriptions
end

class Foo
  GalleryGenerator.add_links_to_descriptions.(nil)
end

或者,您可以使用常量而不是实例变量。常量用大写字母表示:

module GalleryGenerator
  AddLinksToDescriptions = -> mutable_viewable_content {
    mutable_viewable_content.tap do |m|
      m.description = add_links_to_sources(m.description)
    end
  }
end

class Foo
  GalleryGenerator::AddLinksToDescriptions.(nil)
end

或者,你冷使用一个类层次结构变量(用@@ sigil表示):

module GalleryGenerator
  @@add_links_to_descriptions = -> mutable_viewable_content {
    mutable_viewable_content.tap do |m|
      m.description = add_links_to_sources(m.description)
    end
  }
end

class Foo
  include GalleryGenerator
  @@add_links_to_descriptions.(nil)
end

答案 1 :(得分:2)

试试这个:

module GalleryGenerator
  def self.add_links_to_descriptions
    lambda do |mutable_viewable_content|
      mutable_viewable_content.description = add_links_to_sources(mutable_viewable_content.description)
      return mutable_viewable_content
    end
  end
  #...
end

并使用GalleryGenerator.add_links_to_descriptions

进行调用

答案 2 :(得分:1)

只需使lambda为常量或实例方法返回lambda。

module GalleryGenerator
 LINKS_TO_DESCRIPTION_ADDER =  lambda do |mutable_viewable_content|
    mutable_viewable_content.description = add_links_to_sources(mutable_viewable_content.description)
    return mutable_viewable_content
  end
  #...
end

update_using( \
  add_tabs_before_every_description_line(2), \
  LINKS_TO_DESCRIPTION_ADDER)