Quiet new to ruby I can't figure out something. Here's a Sample code

class Big
  def self.metaclass; class << self; self; end; end

  def self.convertor b
    metaclass.instance_eval do
      define_method( :convert ) do |val|
        return b val
       end
    end
  end
end

class Small < Big
  convertor { |v| v.to_i + 1 }
end

puts Small.convert('18')

The aim is to have a lot of subclass to Big and i like to avoid to define in each

def convert(val)
  return conversion_specific_to_subclass(val)
end

Doing the former way i just have one line for each subclass. But can't get it to work. What is it i'm doing wrong? Is there a better way to accomplish what i wish?

Thanks in advance

edit: As asked here are the errors this code produce (with ruby 2.1.0)

test2.rb:4:in `convertor': wrong number of arguments (0 for 1) (ArgumentError)
from test2.rb:14:in `<class:Small>'`
有帮助吗?

解决方案

You're overcomplicating this - since all you want is the ability to bind a block to a specific method name, just do that!

class Big
  def self.converter(&block)
    define_singleton_method :convert, &block
  end
end

class Small < Big
  converter {|v| v.to_i + 1 }
end

That way, when you invoke Small::converter, it will define a class method that accepts a parameter list as defined in your block args, and the return value will be the return value of your block.

其他提示

Try this code:

class Big
  def self.metaclass; class << self; self; end; end

  def self.convertor(&b)
    metaclass.instance_eval do
      define_method( :convert ) do |val|
        return b[val]
       end
    end
  end
end

class Small < Big
  convertor { |v| v.to_i + 1 }
end

puts Small.convert('18')

There were two problems in your code. One, you have to capture the block using an & argument. So, this is the new method declaration:

def self.convertor(&b)

And finally, you have to call the block using block call syntax in your return, like this:

return b[val]

Or this:

return b.call(val)

You cannot call a block like b val.

Also, it's good style in Ruby to always include the parenthesis everywhere.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top