ruby - Ruby中使用eval函数调用其他函数

标签 ruby

我在下面的类中使用 processQuestion 函数来调用其他方法。

这个函数是通过调用其他类的CONSTANTS来调用的。

# Is responsible for executing a particular question. Question types are in the Question object. A question will 
# always have a responding method in this class. That method will take the parameters defined by the question and
# should provide the answer in the format expected.
class QuestionProcessor
  NO_ROUTE = "NO SUCH ROUTE"

  def initialize(routeList)
    @routeList = routeList
  end


  # Finds the method and runs it. This should provide the answer object
  def processQuestion(question)
    return eval("get"+question.command+"(question)")
  end


  # Finds the total distance using the exact stations specified, or returns NO_ROUTE if no route was stored in the route list
  # this method ignores the constraints and actions
  def getDistance(question)
    distance = 0
    currentStation = nil

    question.parameters.each do |nextStation|
      if (! currentStation.nil?)
        route = @routeList.getDirectRoute(currentStation, nextStation)
        if (route.nil?)
          return NO_ROUTE
        end
        distance += route.distance
      end
      currentStation = nextStation;
    end

    return distance;
  end


  # Finds the shortest route possible for the given constraint. This method requires a constraint and action to be provided
  def getShortestRoute(question)
    startStation = question.parameters[0]
    endStation = question.parameters[1]

    routeProcessor = ShortestRouteProcessor.new(@routeList, question.constraint, question.action)
    routeProcessor.getRoute(startStation, endStation)

    return routeProcessor.shortestRoute == Constants::INTEGER_MAX ? NO_ROUTE : routeProcessor.shortestRoute
  end


  # Counts the number of routes based on the condition provided. Intended to count the number of routes, but could potentially provide a total distance
  # or anything else produced by the action.
  def getCountRoutes(question)
    startStation = question.parameters[0]
    endStation = question.parameters[1]

    routeProcessor = RouteProcessor.new(@routeList, question.constraint, question.action)
    routeProcessor.getRoute(startStation, endStation)

    return routeProcessor.totalSuccessfulRoutes 
  end
end

我认为这是保持 DRY 的好方法,但我听说 eval 是邪恶的。

这是好方法还是我应该以更面向对象的方式寻找其他方法?

最佳答案

在这种情况下,您可以安全地使用 send 而不是 eval,就像这个例子:

def processQuestion(question)
  return send("get#{question.command}", question)
end

请注意,如果您不清理您的输入(question.command 在这种情况下)。

如果可能,在调用send(或eval)之前做一个白名单过滤,否则有人可以传递一个命令来做某事你不想做。

关于ruby - Ruby中使用eval函数调用其他函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22095282/

相关文章:

ruby - 禁止 Watir 中的自动关闭窗口

ruby-on-rails - Ubuntu 12.04 上的 Ruby on Rails 段错误

ruby-on-rails - 使用 capybara 运行并行 Selenium 测试

ruby-on-rails - Rails 6 升级中未初始化的常量 ActiveRecord::ConnectionAdapters::ConnectionManagement (NameError)

ruby - 可以从数据库加载专家策略吗?

ruby - 你如何从初始化方法调用类方法?

ruby-on-rails - 当我们只更新一个属性时,我们应该使用强参数吗?

ruby - 你能为现有的 gem 安装文档吗?

ruby-on-rails - 从嵌套类中调用 Ruby 模块方法

ruby-on-rails - 在 Ruby on Rails 中使用 like 查询进行搜索