1

루비에서 출력 인수를 사용하여 메소드를 만들려고합니다.루비 메소드가 출력 매개 변수를 전달하는 방법 (참조 된 인자의 값을 변경)?

나는 인수 가치에 의해 또는 참조에 의한와

나는 엄격한 SENS에, 루비는 항상 패스에 의해 가치가 있음을 undersand 통과 differents의 게시물 here과 거세한 숫양 루비의 토론에 대한 here를 읽을 수 있지만, 전달 된 값은 실제로 참조입니다. 왜 이렇게 많은 논쟁이 벌어 지는지에 대한 이유.

참조 된 변수의 값을 변경하는 방법은 여러 가지가 있음을 알았습니다. 의 경우 배열, 해시 또는 문자열 또는 병합 할 때 메서드를 바꿉니다. 해시입니다.

나는 정수으로, 내가 변경하고 특별한 방법을 사용하지 않고 내 방법 이외의 값을 전달할 것을 알아 냈다.

내 질문에 대한 다른 객체입니다.

class RestaurantController < ApplicationController 
    def pizza_to_deliver(pizza_name, id_of_the_order, pizza) 

     # pizza to eat 
     pizza = Pizza.where(:name => pizza_name).first 

     # unknown pizza 
     return false if pizza.nil? 

     # first customer order about this pizza 
     id_of_the_order = Orders.where(:pizza_id => pizza.id).first 

     true 
    end 
    end 

my_pizza_name = 'margerita' 
My_order_id = nil 
my_pizza = nil 

my_restaurant = RestaurantController.new 

if my_restauant.pizza_to_deliver(my_pizza_name, My_order_id, my_pizza) then 
    puts "Pizza to deliver : #{my_order_id}" 
    rex_dog.eat(my_pizza) 
end 

방법이 작동하는지 확인하기 위해 : 나는 개체의 'id'속성을 검색 할 인스턴스 및 객체 참조 자체에 대한 ? (order_id 및 my_pizza는 nil로 유지됩니다.)

답변

2

Ruby는 Python 및 Java와 마찬가지로 값만 전달합니다. 또한 Python 및 Java와 마찬가지로 객체는 직접 값이 아니며 참조를 통해 조작됩니다.

어떻게 작동하는지 이미 잘 알고있는 것 같습니다. 로컬 변수에 할당하면 호출자 범위에 영향을주지 않습니다. 반환하는 것 외에도 호출자 범위와 정보를 "공유"하려면 전달 된 참조가 가리키는 객체 (해당 메서드가있는 경우, 즉 객체가 변경 가능할 경우)를 "변경"하기 위해 객체의 일부 메서드를 사용해야합니다 . 그러나 이는 단순히 원하는 새 객체에 대한 참조를 제공하는 대신 동일한 객체를 수정합니다.

값을 반환하지 않으려는 경우 호출 된 함수가 변형되어 호출기 범위에 표시되도록 변경할 수있는 변경 가능한 컨테이너 (하나의 요소 배열과 같은)를 전달할 수 있습니다.

다른 옵션은 함수가 블록을 사용하도록하는 것입니다. 이 함수는 블록에 pizza의 새 값을 부여하고 블록 (호출자가 제공 한)이 해당 값으로 처리 할 작업을 결정할 수 있습니다. 호출자는 피자를 자체 범위에 설정하는 블록을 전달할 수 있습니다.

2

대부분 매개 변수는 다중 값 반환을 사용하지 않는 언어의 해결 방법입니다. 루비에서는 함수의 모든 출력 값을 포함하는 Array를 반환 할뿐입니다. 또는 객체의 변수 값을 인스턴스 변수로 만들고 함수를 객체의 메소드로 만듭니다.

0

두 가지 답변 모두에 감사드립니다.

마지막으로 동등한 해결책이 나온 것 같습니다. 변경 가능한 컨테이너.

내 메서드에서 출력 할 매개 변수를 (attr_accessors으로) 포함하는 새 클래스 'OutputParameter'을 만들었습니다. 그런 다음이 클래스의 인스턴스를 내 메서드로 전달했습니다.더 적응성 같이

class OutputParameters 
    attr_accessor :order_id, pizza 
    end 

    class RestaurantController < ApplicationController 
    def pizza_to_deliver(pizza_name, output_parameters) 

     # pizza to eat 
     pizza = Pizza.where(:name => pizza_name).first 

     # unknown pizza 
     return false if pizza.nil? 

     # first customer order about this pizza 
     id_of_the_order = Orders.where(:pizza_id => pizza.id).first 

     # Output values returned 
     output_parameters.pizza = pizza 
     output_parameters.order_id = id_of_the_order 
     true 
    end 
    end 

my_pizza_name = 'margerita' 
my_output = OutputParameters.new 
my_restaurant = RestaurantController.new 

if my_restaurant.pizza_to_deliver(my_pizza_name, my_output) then 
    puts "Pizza to deliver : #{my_output.order_id}" 
    rex_dog.eat(my_output.pizza) 
end 

당신이 제안 해시 또는 배열

심지어 더 나은 아이디어를 보인다 : 나는 클래스를 선언 할 필요가 없다.

난 그냥 병합을 사용합니다! 방법

class RestaurantController < ApplicationController 
    def pizza_to_deliver(pizza_name, output_hash) 

     # pizza to eat 
     pizza = Pizza.where(:name => pizza_name).first 

     # unknown pizza 
     return false if pizza.nil? 

     # first customer order about this pizza 
     id_of_the_order = Orders.where(:pizza_id => pizza.id).first 

     # Output values returned 
     output_hash.merge!({:pizza => pizza}) 
     output_hash.merge!({:id_of_the_order => id_of_the_order}) 
     true 
    end 
    end 

my_pizza_name = 'margerita' 
my_output_hash = {} 
my_restaurant = RestaurantController.new 

if my_restaurant.pizza_to_deliver(my_pizza_name, my_output_hash) then 
    puts "Pizza to deliver : #{my_output_hash[:id_of_the_order]}" 
    rex_dog.eat(my_output_hash[:pizza]) 
end