Geplaatst door Remco van 't Veer
vr, 29 feb 2008 07:25:00 GMT
Waarschuwing: alleen gebruiken onder toezicht van een meerderjarige!
We kennen de whiny nil, zoals toegepast in Rails, maar wat nou whiny?! Bij deze de obedient nil:
class NilClass
def method_missing(*args)
nil
end
end
Geen geklooi meer:
person && person.name && person.name.upcase
Niet echt DRY! Nu met de obedient nil:
person.name.upcase
Het is alweer de laatste dag methode. Ode aan Michiel voor de hoeveelheid gave trucs die hij uit z’n hoge hoed heeft kunnen trekken!
Geplaatst in ruby, dagmethode | 12 reacties
Geplaatst door Michiel de Mare
wo, 27 feb 2008 08:00:00 GMT
Weet je wat ik zo geweldig aan databases vind? En wat ik zo mis aan object-modellen? Dat is dat databases het zo makkelijk maken om data te indexeren.
Stel je voor, je hebt een ongelooflijke bak data, ongeordend, continue veranderend, maar omdat je database een paar indexen bijhoudt kun je toch binnen milliseconden bij elk item dat je wilt.
Zou het niet leuk zijn als dat in Ruby ook kon? Het overkomt me namelijk best vaak dat ik een lijst met honderden items waarin ik wil zoeken. En er overheen itereren wordt al heel snel traag. Dus voor dat ik het weet heb ik overal losse hashes liggen die ik als index gebruik. Maar wat een verschil met een database.
Laten we vandaag een eerste stap in de goede richting zetten met de make_index
methode.
module Enumerable
def make_index(*names)
Struct.new(*names).new(*names.map{|n| group_by(&n)})
end
end
index = User.find(:all).make_index(:login, :id, :nickname)
index.login['mdemare'] => [<#User ...>]
index.nickname['Michiel'] => [<#User ...>]
Voor een andere keer: indices op meer dan één attribuut, en het indexeren van attributen met een natuurlijke ordening.
Geplaatst in ruby, dagmethode | geen reacties
Geplaatst door Michiel de Mare
di, 26 feb 2008 07:52:00 GMT
Zoeken in arrays is best langzaam. Gebruik liever een hash.
Maar als de array al gesorteerd is, kun je een binary search gebruiken. Die werkt door de array doormidden te delen, en vervolgens verder te zoeken in het linker of het rechter deel, net zolang totdat het element gevonden is of er nog maar een element over is..
class Array
def bsearch(k)
x,y = -1,size
while y != x + 1 do
m = (x + y) / 2
if self[m] <= k
x = m
else
y = m
end
end
x >= 0 && self[x] == k && x
end
end
Geplaatst in ruby, dagmethode | 1 reactie
Geplaatst door Michiel de Mare
ma, 25 feb 2008 08:00:00 GMT
Allerminst door ons verzonnen, maar toch vreselijk nuttig en geen onderdeel van de standaard-library: de Levenshteinafstand
Wat berekent het? Hoeveel karakters je moet toevoegen, weghalen of omwisselen om van de ene naar de andere string te gaan. Ideaal voor het detecteren van typefouten.
# example:
levenshtein('levenssteen', 'levenshtein') # => 2
Of wat dacht je voor in plaats van je
LIKE-clause? Niet zo snel misschien (uche uche) maar wel heel goed.
# Vroeger:
User.find(:all,
:conditions => ['name like ?', params[:name] + '%']])
# Nu:
User.find(:all).
sort_by {|u| levenshtein(params[:name], u.name)}.
first
def levenshtein(s1, s2)
d = {}
(0..s1.size).each { |row| d[[row, 0]] = row }
(0..s2.size).each { |col| d[[0, col]] = col }
(1..s1.size).each do |i|
(1..s2.size).each do |j|
i1,j1 = i-1,j-1
cost = s1[i1] != s2[j1] ? 1 : 0
d[[i, j]] = [d[[i1, j1]] + cost,
d[[i1, j]] + 1,
d[[i, j1]] + 1].min
if i1*j1 > 0 and s1[i1] == s2[j-2] and s1[i-2] == s2[j1]
d[[i, j]] = [d[[i,j]] , d[[i-2, j-2]] + cost].min
end
end
end
d[[s1.size, s2.size]]
end
Geplaatst in ruby, dagmethode | 3 reacties