2016-11-20 47 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)