Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing args to class method Ruby

I'm newbie in Jekyll, Ruby. I'm trying to create my custom plugin for Jekyll. So far my code below. I don't understand Ruby compiler behavior, now this code doesn't work, with error undefined method scan, but if I place everything from parse to initialize instead of parse(text), then it starts working.

Complete error: Liquid Exception: undefined method 'scan' for #<Liquid::Tokenizer:0x005577b047a220> in index.html

module Jekyll
  class CreatePicTag < Liquid::Tag
    def initialize(tag_name, text, tokens)
      super
      parse(text)
    end

    def parse(text)
      pattern = /(?<=\[).+?(?=\])/
      @class = text.scan(pattern)[0]
      @alt = text.scan(pattern)[1]
      @path = text.scan(pattern)[2]
    end
  end
end
like image 819
Ramazan Chasygov Avatar asked Apr 10 '26 04:04

Ramazan Chasygov


2 Answers

if I place everything from parse to initialize instead of parse(text), then it starts working

If you can't extract some simple code into a method, something else must be going on.

In this specific case, you are overwriting Liquid's built-in parse method. This method is called internally, so the error you are seeing is caused by Liquid, not by your own call. Unless you are trying to alter Liquid's parsing, you should not implement that method yourself. Liquid needs this method to work properly.

The easiest fix is to simply rename your method, e.g.:

require 'liquid'

class CreatePicTag < Liquid::Tag
  def initialize(tag_name, text, tokens)
    super
    parse_text(text)
  end

  def parse_text(text)
    pattern = /(?<=\[).+?(?=\])/
    @class = text.scan(pattern)[0]
    @alt   = text.scan(pattern)[1]
    @path  = text.scan(pattern)[2]
  end

  def render(context)
    [@class, @alt, @path].join('|')
  end
end

Liquid::Template.register_tag('create_pig', CreatePicTag)
@template = Liquid::Template.parse("{% create_pig [foo][bar][baz] %}")
p @template.render

Output:

foo|bar|baz
like image 54
Stefan Avatar answered Apr 11 '26 18:04

Stefan


Verify whether the text has any scan method on it before calling it:

module Jekyll
  class CreatePicTag < Liquid::Tag
    def initialize(tag_name, text, tokens)
      super
      parse(text)
    end

    def parse(text)
      pattern = /(?<=\[).+?(?=\])/
      if text.respond_to?(:scan)
        @class = text.scan(pattern)[0]
        @alt = text.scan(pattern)[1]
        @path = text.scan(pattern)[2]
      end
    end
  end
end

and call it like this:

Jekyll::CreatePicTag.new(tag_name, text, tokens)
like image 45
Sachin Singh Avatar answered Apr 11 '26 17:04

Sachin Singh