Search code examples
rubycompass

reuse hooks from compass' config.rb


I have multiple shops, each being a standalone project. What I need is a way to include common hooks from a library of hooks from a location shared across them (in the following code, only on_stylesheet_saved.

config.rb looks something like this:

http_path = "/"
css_dir = "public/css/live/"
sass_dir = "public/css/entrypoints"
images_dir = "public/library/images"
javascripts_dir = "public/library/javascript"
additional_import_paths = [ "public/library/css" ]

output_style = (environment == :production) ? :compressed : :expanded

relative_assets = false

if environment == :production
    on_stylesheet_saved do |filename|
          #do stuff
    end
else
    load 'temp.rb'
end

the line load 'temp.rb' is executed, however the hook inside is not, when I change a scss file:

on_stylesheet_saved do |filename|
    puts "XXX #{filename}"
end

How to properly load this temp.rb hook without duplicating the code across all shops?

PS: the project is not in ruby, and I'm not a ruby programmer. The code base is of medium size, over 300k LOCs, so no big refactorings come into question. We are merely using compass as a tool.


Solution

  • Per comments, there's a chance that the context is different in the two files.

    Seeing how p self is, in config.rb:

    #<Compass::Configuration::FileData:0x00000000af6a68 ...>
    

    ... vs main in temp.rb.

    I'd advise one of two options:

    1. Read the file as a string and eval it: eval str

    2. Read the file as a string and instance_eval it: instance_eval str, __FILE__, __LINE__

    The difference between the two isn't material in your particular case, since the context is that the object you're targeting already. Unless you're interested in having the precise file and line where a ruby error might be occurring.

    For information though, instance_eval, module_eval, and class_eval offer a convenient way to change the context when needed:

    class Foo; end
    p self                           # main
    Foo.new.instance_eval("p self")  # a Foo instance
    Foo.new.module_eval("p self")    # undefined method
    Foo.new.class_eval("p self")     # undefined method
    Foo.instance_eval("p self")      # the Foo class
    Foo.module_eval("p self")        # the Foo class
    Foo.class_eval("p self")         # the Foo class