2016-11-20 67 views
1

所以我开始学习ruby,我发现我们可以在方法中使用默认值,这看起来类似于只有实例变量,除了减少行数之外,是否有任何重要性或好处?码?红宝石:参数与变量

//这

def order_food(price, size="large", quantity = 8) 
    if quantity == 1 
     extra = "salad" 
    else 
     extra = "Burgers" 
    end 
    puts "#{quantity} #{size} #{extra}, coming right up!" 
    end 

//对此

def order_food(price) 
    size = "large" 
    quantity = 8 
    if quantity == 1 
     extra = "salad" 
    else 
     extra = "Burgers" 
    end 
    puts "#{quantity} #{size} #{extra}, coming right up!" 
    end 
+1

'size'和'quantity'不是实例变量。这将是'@ size'和'@ quantity'。 – Schwern

+0

完全混合,改变了。由于@Schwern – ekeith

+0

什么是您的两个方法'price'参数的目的是什么? –

回答

4

而深刻的思考这个,我意识到这提供了非常大的好处之一是灵活性和可读性。 因此,例如,我可以在参数传似

order_food(2, "small", 90) 

这让我覆盖默认值比具有同时

order_food(9, "extraLarge") 

得到默认的量来改变内容的变量更好,我已设置

2

首先,变量是局部变量而不是实例变量。实例变量属于某个类的实例,并且使用@var_name表示法进行标记,而局部变量属于作用域(非常简单,即由do ... end包围的任何内容,更多详细信息here),并且仅使用变量名称(my_var = "some_value") 。

这取决于你使用的方法。如果您希望能够传递参数quantitysize,则应该使用第一个参数。如果您尝试传递多于1个参数,第二个会给你和ArgumentError。如果它们未被传递,第一个将设置值quantity = 8size = "large",但如果它们被传递,它将使用传递的值。

如果你希望能够调用的方法和设置的大小和数量作为参数,如果他们没有通过使用size = "large"quantity = 8作为默认值,使用第一种方法:

order_food "9.00" #=> "8 large burgers, coming right up!" 
order_food "9.00", "small", 1 #=> "1 small salad, coming right up!" 

第二种方法将不允许您传递其他两个参数中的任何一个,并且它们将始终设置为quantity = 8size = "large"。这有好处,因为有时候你不希望变量可以随参数变化。所以采用第二种方法:

order_food "9.00" #=> "8 large burgers, coming right up!" 
order_food "9.00", "small", 1 #=> ArgumentError: wrong number of arguments (given 3, expected 1) 
3

它与实例变量不一样。一个实例变量有一个类的实例的范围,并使用@符号声明。

例如:

class MyClass 

    def initialise 
    @my_instance_variable = 'hello world' 
    end 

    def method_one 
    puts "I have access to the instance variable and it is #{@my_instance_variable}" 
    end 
end 

什么,你已经证明是局部变量的声明都对方法而已,但是一个被定义参数传递给方法的范围,另一种是没有。

def order_food(price, size="large", quantity = 8)

的当量:

def order_food(price) 
    size = "large" 
    quantity = 8 

虽然尺寸和数量是两个变量并且两者都具有范围只为order_food方法中,第一被声明为参数的方法可以接受,所以它可以这样调用:

order_food(5, 'small', 2) 

Wher在第二个例子中,这些不能由被调用者设置 - 它们被固定为“大”和8.

没有必要用默认值声明方法参数,但这样做被调用者不需要提供它们并且将使用默认值。因此,对于的方法声明:

def order_food(price, size="large", quantity = 8)

你可以做以下电话:

order_food price: 10, quantity: 2 #will use default size with value 'large' 
order_food price: 5, size: 'small' #will use default quantity of 8 
1

这是你的代码的重新返工的版本,更红宝石般:

def order_food(price, size: :large, quantity: 1) 
    extras = 
    case (quantity) 
    when 1 
     "salad" 
    else 
     "Burgers" 
    end 

    "#{quantity} #{size} #{extra}, coming right up!" 
end 

puts order_food(2, :small, 8) 

在方法内部做显示(puts)通常会给方法太多的责任。从构图上分解出显示问题。也许你想把它写到一个文件中,或者将它嵌入到HTML中。该方法内部的puts限制了您的选项。

如果你想让它们的数量在本质上有些任意,也可以利用关键字参数。这允许你跳过一个并使用另一个,而不必重新指定默认值。

0

实际上有4种常用的方法将参数传递给函数。 你的第一个例子是最常见的例子,但是你害怕做出了一个糟糕的例子。您的数量始终是8,所以如果是多余的,也没有使用,因此也多余 的parametere价格这将是相同以下

def order_food price 
     "8 large Burgers, coming right up!" 
    end 

但是,这是不是你的目的我相信。

所以,这会是这样 第一种方法的东西

def order_food1(size, quantity, price) 
    extra = quantity == 1 ? :salad : :Burgers 
    cost = quantity * price 
    "#{quantity} #{size} #{extra}, coming right up! Thats is #{cost} dollar please" 
end 

+快(见基准)

+每个人都使用它,了解它在一个糖霜

- 你要知道它们所定义的参数和顺序,你需要阅读的不太常见的应用方法的API

- 你必须提供所有的参数

下一页:使用可选参数使用默认值

def order_food2(size = "large", quantity = 1, price = 4) 
    extra = quantity == 1 ? :salad : :Burgers 
    cost = quantity * price 
    "#{quantity} #{size} #{extra}, coming right up! Thats is #{cost} dollar please" 
end 

+还广泛应用于

+没有必要,如果他们是在默认的使用参数

- 你还需要知道的参数的顺序和意义,如果最后使用你需要他们所有

下一页:使用哈希作为参数

def order_food3(opts = {}) 
    opts = {size: :large, quantity: 1, price: 4}.merge!(opts) 
    extra = opts[:quantity] == 1 ? :salad : :Burgers 
    cost = opts[:quantity] * opts[:price] 
    "#{opts[:quantity]} #{opts[:size]} #{extra}, coming right up! Thats is #{cost} dollar please" 
end 

- 少用,你的方法自己是有点难以阅读

- 慢

+不需要知道参数你不不需要,也没有订单

+该方法的使用更具可读性

下一页:以前的方法

def order_food4(size: :large, quantity: 1, price: 4) 
    extra = :quantity == 1 ? :salad : :Burgers 
    cost = quantity * price 
    "#{quantity} #{size} #{extra}, coming right up! Thats is #{cost} dollar please" 
end 

的简化版本 - 慢

+方法本身和使用它的可读性更强

哪一个更好?取决于个人的品味和情况。 我使用所有的人,并没有什么设计指南,据我知道,prefares一方或另一方。在实践中,你甚至会将其中的一些组合起来。那些很少改变 参数,最好给出一个默认值,反之亦然。 的方法是所谓多次(如递归的)能够从更快,更少的内存消耗方法1. 在我看来受益,可读性是一个Ruby脚本最重要的,所以如果有很多的参数和使用feasable方法3或4

使用和标准的一些例子..

puts order_food1("large", 3, 4) 
puts order_food2("large", 3, 4) 
puts order_food3(size: "large", quantity: 3, price: 4) 
puts order_food3 
puts order_food4(size: "large", quantity: 3, price: 4) 
puts order_food4 

# 3 large Burgers, coming right up! Thats is 12 dollar please 
# 3 large Burgers, coming right up! Thats is 12 dollar please 
# 3 large Burgers, coming right up! Thats is 12 dollar please 
# 1 large salad, coming right up! Thats is 4 dollar please 
# 3 large Burgers, coming right up! Thats is 12 dollar please 
# 1 large Burgers, coming right up! Thats is 4 dollar please 

require 'benchmark' 

Benchmark.bmbm do |x| 
    x.report("order_food1 ") { 10000.times { order_food1("large", 3, 12) }} 
    x.report("order_food2 ") { 10000.times { order_food2("large", 3, 12) }} # all parameters given 
    x.report("order_food2_def") { 10000.times { order_food2 }} # using default parameters 
    x.report("order_food3 ") { 10000.times { order_food3(size: "large", quantity: 3, price: 12) }} # all parameters given 
    x.report("order_food3 def") { 10000.times { order_food3 }} # using default parameters 
    x.report("order_food4 ") { 10000.times { order_food3(size: "large", quantity: 3, price: 12) }} # all parameters given 
    x.report("order_food4 def") { 10000.times { order_food3 }} # using default parameters 
end 

#      user  system  total  real 
# order_food1  0.015000 0.000000 0.015000 ( 0.010420) 
# order_food2  0.000000 0.000000 0.000000 ( 0.010675) 
# order_food2_def 0.016000 0.000000 0.016000 ( 0.011007) 
# order_food3  0.015000 0.000000 0.015000 ( 0.020182) 
# order_food3 def 0.016000 0.000000 0.016000 ( 0.016954) 
# order_food4  0.015000 0.000000 0.015000 ( 0.020256) 
# order_food4 def 0.000000 0.000000 0.000000 ( 0.016968)