Meta programming problem

Hi,

i've wrote the following code module TeamScore
  class Filter
    ALLOWED_RESOURCES = [:game]

    # convert <game:4 title> into markdown link to game re
    # use game title as link name
    # "Google":http://google.com.

Hi,

i've wrote the following code module TeamScore
  class Filter
    ALLOWED_RESOURCES = [:game]

    # convert <game:4 title> into markdown link to game re
    # use game title as link name
    # "Google":http://google.com.
    #
    def self.filter(str)
      str.gsub(/<([a-z]+):(\d+)>/) do |match|
        create_link_for($1.to_sym,$2, match)
      end
    end

    def self.create_link_for(resource_type, id, match)
      raise "Macro #{match} not allowed" unless
ALLOWED_RESOURCES.include?(resource_type.to_sym)
      case resource_type
        when :game
          model = Game
        when :article
          model = Article
      end
      object = model.send("find", id)

"\"#{object.name}\":www.teamscore.org/#{object.class.name.pluralize.downcase}/#{object.id}"
    end
  end
end

How i can dry case when block.

Remove it altogether :wink: see below.

My idea is to send a find message to model coresponding the
resource_type argument but resource_type is a string (previously
extracted from regexp) and I can't use ressource_type.send(....)
or send("#{ressource_type.classify}.find", id) the 2 stament raise an
error (NoMethodError: undefined method `Game' for
TeamScore::Filter:Class)

You don't need the send here. Send without an object tries to execute
send on the current scope, which would be TeamScore::Filter. In this
case, you are trying to execute self.Game.find(id), which is of course
not valid (unless you happened to have a constant called Game defined
on the class...).

Try resource_type.classify.find(id).

resource_type.classify will simply return the class (Game or Article),
which you can happily call any methods on.

Cheers,
Max

Max Muermann a écrit :

Remove it altogether :wink: see below.

> My idea is to send a find message to model coresponding the
> resource_type argument but resource_type is a string (previously
> extracted from regexp) and I can't use ressource_type.send(....)
> or send("#{ressource_type.classify}.find", id) the 2 stament raise an
> error (NoMethodError: undefined method `Game' for
> TeamScore::Filter:Class)

You don't need the send here. Send without an object tries to execute
send on the current scope, which would be TeamScore::Filter. In this
case, you are trying to execute self.Game.find(id), which is of course
not valid (unless you happened to have a constant called Game defined
on the class...).

Try resource_type.classify.find(id).

resource_type.classify will simply return the class (Game or Article),
which you can happily call any methods on.

Cheers,
Max

Thanks,

I've try it but this doesn't work.
I've got an LocalJumpError or something like this. I think it try to
invoke find on a String not on the Game or Article. The classify method
just retunr a string in my mind.

Guillaume :

> You don't need the send here. Send without an object tries to execute
> send on the current scope, which would be TeamScore::Filter. In this
> case, you are trying to execute self.Game.find(id), which is of course
> not valid (unless you happened to have a constant called Game defined
> on the class...).
>
> Try resource_type.classify.find(id).
>
> resource_type.classify will simply return the class (Game or Article),
> which you can happily call any methods on.

Thanks,

I've try it but this doesn't work.
I've got an LocalJumpError or something like this. I think it try to
invoke find on a String not on the Game or Article. The classify method
just retunr a string in my mind.

Try :

  resource_type.classify.constantize.find(id)

    -- Jean-François.

This work great.

Thank a lot.

Jean-François a écrit :