In Ruby, how can I refer to a lambda that is defined in a module?

This code was used until I included my lambda function in the module.

Here is the lambda function:

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

      

This is how it is used:

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)

      

What's the error:

/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>'

      

If the lambda message is not in the module everything works. I suspect it is looking for @add_links_to_descriptions in the wrong place now that in a module ...

How can I fix this? Thank!

+3


source to share


3 answers


try this:

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

      



and call it GalleryGenerator.add_links_to_descriptions

+2


source


In Ruby, variables that start with a symbol @

are instance variables, that is, variables that belong to a particular object (or instance).

In this case, the instance variable @add_links_to_descriptions

belongs to the object referenced by the constant GalleryGenerator

and can only be accessed by one object.

The only things available to other objects in Ruby are methods. So, you need to define a method that returns the value of an instance variable. Such a method is called an attribute reader in Ruby, and there is a convenient method for generating them automatically called Module#attr_reader

:

class << GalleryGenerator
  attr_reader :add_links_to_descriptions
end

class Foo
  GalleryGenerator.add_links_to_descriptions.(nil)
end

      



Alternatively, you can use a constant instead of an instance variable. Constants are capitalized:

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

      

Or you use the cold version of the class hierarchy variable (denoted by a symbol @@

):

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

      

+2


source


Just make lambda

a constant or instance method that returns a 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)

      

+1


source







All Articles