Was Sie fordern, ist während der Hash-Deklaration nicht möglich. Sie können Ihren Code wie folgt ändern:
purchase = {}
purchase[:product] = 'phone'
purchase[:quantity] = 5
purchase[:price] = 120
purchase[:total] = purchase[:quantity] * purchase[:price]
Oder einfach nur die letzte Zeile:
purchase = {
product: 'phone',
quantity: 5,
price: 120
}
purchase[:total] = purchase[:quantity] * purchase[:price]
oder andere dumme Art und Weise, die etwas weniger Tipp beinhalten:
purchase = {
product: 'phone',
quantity: 5,
price: 120
}.tap{ |h| h[:total] = h[:quantity] * h[:price] }
Allerdings würde ich vorschlagen In einem Fall wie diesem sollten Sie "denormalized" data NICHT in Ihrem Hash speichern. Da total
von der Menge oder dem Preis abhängig ist, wird der Hash ungültig, wenn sich einer der beiden ändert.
Sie können dieses Problem umgehen, indem Sie eine spezielle default_proc
auf Hash erstellen, die im laufenden Betrieb jedes Mal die Gesamt berechnet sie angefordert wird:
purchase = {
product: 'phone',
quantity: 5,
price: 120
}
purchase.default_proc = ->(h,k){
h[:quantity]*h[:price] if k==:total
}
p purchase[:total] #=> 600
purchase[:quantity] = 7
p purchase[:total] #=> 840
Allerdings wäre es klar sein, eine Klasse oder Struktur zu erstellen um dies zu tun. Ein Struct ist weniger Code für Sie:
Purchase = Struct.new(:product,:quantity,:price) do
def total
quantity * price
end
end
purchase = Purchase.new('phone',5,120)
p purchase.total #=> 600
purchase.quantity = 3
p purchase.total #=> 360
jedoch die Struct nicht (by default) Keyword-Argumente ermöglichen. Durch Ihre eigene Klasse schreiben, können Sie die Argumente in beliebiger Reihenfolge, liefern und sogar einen Standardwert bieten:
class Purchase
attr_reader :product, :price, :quantity
def initialize(product:,price:,quantity:1) # default quantity
@product, @price, @quantity = product, price, quantity
end
def total
price*quantity
end
end
Purchase.new(price:10, product:'shoes').total #=> 10
Purchase.new(product:'shoes', price:10).total #=> 10
Purchase.new(quantity:3, price:10, product:'shoes').total #=> 30
möchten Sie beim Initialisieren Hash seine einige Werte basierend auf anderen Schlüsseln? – Thorin
ja, das ist es. –