2014-02-28 76 views
2

我使用下面的類與processQuestion函數調用其他方法。在Ruby中使用eval函數調用其他函數

通過調用其他類的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 

我認爲這是一個很好的方法來保持乾燥,但我聽到eval是邪惡的。

這是一個好方法,還是應該以更面向對象的方式尋找其他方法?

+0

見http://stackoverflow.com/questions/1902744/when-is-eval-in- ruby-justified&http://stackoverflow.com/questions/637421/is-eval-supposed-to-be-nasty – Agis

回答

3

在這種情況下,你可以放心地在這個例子中使用send代替eval,如:

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

要知道,如果你不淨化你的輸入send可能爲eval危險(question.command在這種情況下)。

如果可能的話,請致電send(或eval)之前白名單過濾,否則有人可以通過它做你不想做的事情的命令。

+0

send和eval有什麼區別? –

+0

@PassionateDeveloper評估任何東西。發送發送消息。 –

+0

所以發送更安全,因爲它更受限制? –

相關問題