Onze dagmethode #10: Object#r[rs][ds]s
Geplaatst door Michiel de Mare ma, 18 feb 2008 08:00:00 GMT
Ruby 1.9 heeft Object#tap
. Lang geleden introduceerde DannyObject#with
. Dan is er nog Object#instance_eval
.
Hebben deze methodes iets gemeen behalve hun raadselachtige namen?
Het blijkt van wel.Deze methoden vallen in de familie methoden die:- Voor elk
Object
gedefinieerd zijn. - Een block nemen en dat altijd éénmaal uitvoeren
- Niets anders doen
Misschien verbaast het je dat er maar liefst drie methoden in deze categorie zijn. En er is zelfs nog een vierde!
Want zelfs binnen deze strenge specificaties zijn er nog een paar openstaande punten:- Wat retourneren we? Het object zelf? Of het resultaat van het block?
- Binnen het block, wat is
self
? Is het het object? Of is het onveranderd (waardoor we het object als argument moeten meegeven)?
tap
: retourneert resultaat, zelfdeself
in blockwith
: retourneertself
, zelfdeself
in blockinstance_eval
: retourneert resultaat, andereself
in block.
switch
: retourneertself
, andereself
in block.
Laten we deze methoden in actie zien!
name = group.owner.name
name = "bar" if name =~ /foo/
name.split(' ')
# met with
group.owner.name.with {|n| n =~ /foo/ ? 'bar' : n}.split(' ')
b = foo.bar
raise unless b
b.baz.goo
# met tap
foo.bar.tap{|o| raise unless o}.baz.goo
p = user.instance_variable_get("@secret")
user.instance_variable_set("@secret", p + "1")
# met instance_eval
user.instance_eval {@secret += "1"}
def User.create_test_user
(u = new).instance_eval do
@name = "test"
@admin = true
end
u
end
# met switch
def User.create_test_user
new.switch do
@name = "test"
@admin = true
end
end
Dat brengt me op mijn laatste punt. Ik kan die rottige namen maar niet onthouden! En instance_eval is veeeel te lang. Daarom stel ik deze afkortingen als namen voor:
tap => rsss
: Returns Self Same Selfwith => rrss
: Returns Result Same Selfinstance_eval => rsds
: Returns Self Different Selfswitch => rrds
: Returns Result Different Self