我在下面的类中使用 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/