2
0
Selaa lähdekoodia

Merge pull request #213 from alesch/issue193

Fixed issue #193.
Nicolas Petton 12 vuotta sitten
vanhempi
commit
1fd1725073

+ 2 - 2
js/Kernel-Collections.deploy.js

@@ -653,7 +653,7 @@ smalltalk.method({
 selector: "at:ifPresent:",
 fn: function (aKey, aBlock){
 var self=this;
-return (($receiver = smalltalk.send(self, "_basicAt_", [aKey])) != nil && $receiver != undefined) ? (function(){return smalltalk.send(aBlock, "_value_", [smalltalk.send(self, "_at_", [aKey])]);})() : nil;
+return ((($receiver = smalltalk.send(self, "_includesKey_", [aKey])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(aBlock, "_value_", [smalltalk.send(self, "_at_", [aKey])]);})() : (function(){return nil;})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return smalltalk.send(aBlock, "_value_", [smalltalk.send(self, "_at_", [aKey])]);}), (function(){return nil;})]));
 return self;}
 }),
 smalltalk.HashedCollection);
@@ -664,7 +664,7 @@ smalltalk.method({
 selector: "at:ifPresent:ifAbsent:",
 fn: function (aKey, aBlock, anotherBlock){
 var self=this;
-return smalltalk.send(smalltalk.send(self, "_basicAt_", [aKey]), "_ifNil_ifNotNil_", [anotherBlock, (function(){return smalltalk.send(aBlock, "_value_", [smalltalk.send(self, "_at_", [aKey])]);})]);
+return smalltalk.send(smalltalk.send(self, "_includesKey_", [aKey]), "_ifTrue_ifFalse_", [(function(){return smalltalk.send(aBlock, "_value_", [smalltalk.send(self, "_at_", [aKey])]);}), anotherBlock]);
 return self;}
 }),
 smalltalk.HashedCollection);

+ 6 - 6
js/Kernel-Collections.js

@@ -930,11 +930,11 @@ selector: "at:ifPresent:",
 category: 'accessing',
 fn: function (aKey, aBlock){
 var self=this;
-return (($receiver = smalltalk.send(self, "_basicAt_", [aKey])) != nil && $receiver != undefined) ? (function(){return smalltalk.send(aBlock, "_value_", [smalltalk.send(self, "_at_", [aKey])]);})() : nil;
+return ((($receiver = smalltalk.send(self, "_includesKey_", [aKey])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(aBlock, "_value_", [smalltalk.send(self, "_at_", [aKey])]);})() : (function(){return nil;})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return smalltalk.send(aBlock, "_value_", [smalltalk.send(self, "_at_", [aKey])]);}), (function(){return nil;})]));
 return self;},
 args: ["aKey", "aBlock"],
-source: "at: aKey ifPresent: aBlock\x0a\x09^(self basicAt: aKey) ifNotNil: [aBlock value: (self at: aKey)]",
-messageSends: ["ifNotNil:", "basicAt:", "value:", "at:"],
+source: "at: aKey ifPresent: aBlock\x0a\x09\x22Lookup the given key in the receiver. \x0a\x09If it is present, answer the value of evaluating the given block with the value associated with the key. \x0a\x09Otherwise, answer nil.\x22\x0a\x09^(self includesKey: aKey)\x0a\x09\x09ifTrue: [ aBlock value: (self at: aKey) ]\x0a\x09\x09ifFalse: [ nil ]",
+messageSends: ["ifTrue:ifFalse:", "includesKey:", "value:", "at:"],
 referencedClasses: []
 }),
 smalltalk.HashedCollection);
@@ -946,11 +946,11 @@ selector: "at:ifPresent:ifAbsent:",
 category: 'accessing',
 fn: function (aKey, aBlock, anotherBlock){
 var self=this;
-return smalltalk.send(smalltalk.send(self, "_basicAt_", [aKey]), "_ifNil_ifNotNil_", [anotherBlock, (function(){return smalltalk.send(aBlock, "_value_", [smalltalk.send(self, "_at_", [aKey])]);})]);
+return smalltalk.send(smalltalk.send(self, "_includesKey_", [aKey]), "_ifTrue_ifFalse_", [(function(){return smalltalk.send(aBlock, "_value_", [smalltalk.send(self, "_at_", [aKey])]);}), anotherBlock]);
 return self;},
 args: ["aKey", "aBlock", "anotherBlock"],
-source: "at: aKey ifPresent: aBlock ifAbsent: anotherBlock\x0a\x09^(self basicAt: aKey)\x0a\x09    ifNil: anotherBlock\x0a\x09    ifNotNil: [aBlock value: (self at: aKey)]",
-messageSends: ["ifNil:ifNotNil:", "basicAt:", "value:", "at:"],
+source: "at: aKey ifPresent: aBlock ifAbsent: anotherBlock\x0a\x09\x22Lookup the given key in the receiver. \x0a\x09If it is present, answer the value of evaluating the oneArgBlock with the value associated with the key, \x0a\x09otherwise answer the value of absentBlock.\x22\x0a\x09^(self includesKey: aKey)\x0a\x09\x09ifTrue: [ aBlock value: (self at: aKey) ]\x0a\x09\x09ifFalse: anotherBlock",
+messageSends: ["ifTrue:ifFalse:", "includesKey:", "value:", "at:"],
 referencedClasses: []
 }),
 smalltalk.HashedCollection);

+ 55 - 0
js/Kernel-Tests.deploy.js

@@ -369,6 +369,61 @@ return self;}
 }),
 smalltalk.DictionaryTest);
 
+smalltalk.addMethod(
+"_testIfAbsent",
+smalltalk.method({
+selector: "testIfAbsent",
+fn: function (){
+var self=this;
+var d=nil;
+var visited=nil;
+(visited=false);
+(d=smalltalk.send((smalltalk.Dictionary || Dictionary), "_new", []));
+smalltalk.send(d, "_at_ifAbsent_", ["hello", (function(){return (visited=true);})]);
+smalltalk.send(self, "_assert_", [visited]);
+return self;}
+}),
+smalltalk.DictionaryTest);
+
+smalltalk.addMethod(
+"_testIfPresent",
+smalltalk.method({
+selector: "testIfPresent",
+fn: function (){
+var self=this;
+var d=nil;
+var visited=nil;
+var absent=nil;
+(visited=false);
+(d=smalltalk.send((smalltalk.Dictionary || Dictionary), "_new", []));
+smalltalk.send(d, "_at_put_", ["hello", "world"]);
+smalltalk.send(d, "_at_ifPresent_", ["hello", (function(value){return (visited=value);})]);
+smalltalk.send(self, "_assert_", [smalltalk.send(visited, "__eq", ["world"])]);
+(absent=smalltalk.send(d, "_at_ifPresent_", ["bye", (function(value){return (visited=value);})]));
+smalltalk.send(self, "_assert_", [smalltalk.send(absent, "_isNil", [])]);
+return self;}
+}),
+smalltalk.DictionaryTest);
+
+smalltalk.addMethod(
+"_testIfPresentIfAbsent",
+smalltalk.method({
+selector: "testIfPresentIfAbsent",
+fn: function (){
+var self=this;
+var d=nil;
+var visited=nil;
+(visited=false);
+(d=smalltalk.send((smalltalk.Dictionary || Dictionary), "_new", []));
+smalltalk.send(d, "_at_put_", ["hello", "world"]);
+smalltalk.send(d, "_at_ifPresent_ifAbsent_", ["hello", (function(value){return (visited=value);}), (function(){return (visited=true);})]);
+smalltalk.send(self, "_assert_", [smalltalk.send(visited, "__eq", ["world"])]);
+smalltalk.send(d, "_at_ifPresent_ifAbsent_", ["buy", (function(value){return (visited=value);}), (function(){return (visited=true);})]);
+smalltalk.send(self, "_assert_", [visited]);
+return self;}
+}),
+smalltalk.DictionaryTest);
+
 smalltalk.addMethod(
 "_testKeys",
 smalltalk.method({

+ 70 - 0
js/Kernel-Tests.js

@@ -489,6 +489,76 @@ referencedClasses: ["Dictionary"]
 }),
 smalltalk.DictionaryTest);
 
+smalltalk.addMethod(
+"_testIfAbsent",
+smalltalk.method({
+selector: "testIfAbsent",
+category: 'tests',
+fn: function (){
+var self=this;
+var d=nil;
+var visited=nil;
+(visited=false);
+(d=smalltalk.send((smalltalk.Dictionary || Dictionary), "_new", []));
+smalltalk.send(d, "_at_ifAbsent_", ["hello", (function(){return (visited=true);})]);
+smalltalk.send(self, "_assert_", [visited]);
+return self;},
+args: [],
+source: "testIfAbsent\x0a\x0a\x09| d visited |\x0a\x09visited := false.\x0a\x09d := Dictionary new.\x0a\x0a\x09d at: 'hello' ifAbsent: [ visited := true ].\x0a\x09self assert: visited.",
+messageSends: ["new", "at:ifAbsent:", "assert:"],
+referencedClasses: ["Dictionary"]
+}),
+smalltalk.DictionaryTest);
+
+smalltalk.addMethod(
+"_testIfPresent",
+smalltalk.method({
+selector: "testIfPresent",
+category: 'tests',
+fn: function (){
+var self=this;
+var d=nil;
+var visited=nil;
+var absent=nil;
+(visited=false);
+(d=smalltalk.send((smalltalk.Dictionary || Dictionary), "_new", []));
+smalltalk.send(d, "_at_put_", ["hello", "world"]);
+smalltalk.send(d, "_at_ifPresent_", ["hello", (function(value){return (visited=value);})]);
+smalltalk.send(self, "_assert_", [smalltalk.send(visited, "__eq", ["world"])]);
+(absent=smalltalk.send(d, "_at_ifPresent_", ["bye", (function(value){return (visited=value);})]));
+smalltalk.send(self, "_assert_", [smalltalk.send(absent, "_isNil", [])]);
+return self;},
+args: [],
+source: "testIfPresent\x0a\x0a\x09| d visited absent |\x0a\x09visited := false.\x0a\x09d := Dictionary new.\x0a\x09d at: 'hello' put: 'world'.\x0a\x0a\x09d at: 'hello' ifPresent: [ :value | visited := value ].\x0a\x09self assert: visited = 'world'.\x0a\x0a\x09absent := d at: 'bye' ifPresent: [ :value | visited := value ].\x0a\x09self assert: absent isNil.\x0a",
+messageSends: ["new", "at:put:", "at:ifPresent:", "assert:", "=", "isNil"],
+referencedClasses: ["Dictionary"]
+}),
+smalltalk.DictionaryTest);
+
+smalltalk.addMethod(
+"_testIfPresentIfAbsent",
+smalltalk.method({
+selector: "testIfPresentIfAbsent",
+category: 'tests',
+fn: function (){
+var self=this;
+var d=nil;
+var visited=nil;
+(visited=false);
+(d=smalltalk.send((smalltalk.Dictionary || Dictionary), "_new", []));
+smalltalk.send(d, "_at_put_", ["hello", "world"]);
+smalltalk.send(d, "_at_ifPresent_ifAbsent_", ["hello", (function(value){return (visited=value);}), (function(){return (visited=true);})]);
+smalltalk.send(self, "_assert_", [smalltalk.send(visited, "__eq", ["world"])]);
+smalltalk.send(d, "_at_ifPresent_ifAbsent_", ["buy", (function(value){return (visited=value);}), (function(){return (visited=true);})]);
+smalltalk.send(self, "_assert_", [visited]);
+return self;},
+args: [],
+source: "testIfPresentIfAbsent\x0a\x0a\x09| d visited |\x0a\x09visited := false.\x0a\x09d := Dictionary new.\x0a\x09d at: 'hello' put: 'world'.\x0a\x0a\x09d at: 'hello' ifPresent: [ :value | visited := value ] ifAbsent: [ visited := true ].\x0a\x09self assert: visited = 'world'.\x0a\x0a\x09d at: 'buy' ifPresent: [ :value | visited := value ] ifAbsent: [ visited := true ].\x0a\x09self assert: visited.",
+messageSends: ["new", "at:put:", "at:ifPresent:ifAbsent:", "assert:", "="],
+referencedClasses: ["Dictionary"]
+}),
+smalltalk.DictionaryTest);
+
 smalltalk.addMethod(
 "_testKeys",
 smalltalk.method({

+ 12 - 4
st/Kernel-Collections.st

@@ -304,13 +304,21 @@ at: aKey ifAbsentPut: aBlock
 !
 
 at: aKey ifPresent: aBlock
-	^(self basicAt: aKey) ifNotNil: [aBlock value: (self at: aKey)]
+	"Lookup the given key in the receiver. 
+	If it is present, answer the value of evaluating the given block with the value associated with the key. 
+	Otherwise, answer nil."
+	^(self includesKey: aKey)
+		ifTrue: [ aBlock value: (self at: aKey) ]
+		ifFalse: [ nil ]
 !
 
 at: aKey ifPresent: aBlock ifAbsent: anotherBlock
-	^(self basicAt: aKey)
-	    ifNil: anotherBlock
-	    ifNotNil: [aBlock value: (self at: aKey)]
+	"Lookup the given key in the receiver. 
+	If it is present, answer the value of evaluating the oneArgBlock with the value associated with the key, 
+	otherwise answer the value of absentBlock."
+	^(self includesKey: aKey)
+		ifTrue: [ aBlock value: (self at: aKey) ]
+		ifFalse: anotherBlock
 !
 
 at: aKey put: aValue

+ 38 - 0
st/Kernel-Tests.st

@@ -266,6 +266,44 @@ testEquality
 	self deny: d1 = d2.
 !
 
+testIfAbsent
+
+	| d visited |
+	visited := false.
+	d := Dictionary new.
+
+	d at: 'hello' ifAbsent: [ visited := true ].
+	self assert: visited.
+!
+
+testIfPresent
+
+	| d visited absent |
+	visited := false.
+	d := Dictionary new.
+	d at: 'hello' put: 'world'.
+
+	d at: 'hello' ifPresent: [ :value | visited := value ].
+	self assert: visited = 'world'.
+
+	absent := d at: 'bye' ifPresent: [ :value | visited := value ].
+	self assert: absent isNil.
+!
+
+testIfPresentIfAbsent
+
+	| d visited |
+	visited := false.
+	d := Dictionary new.
+	d at: 'hello' put: 'world'.
+
+	d at: 'hello' ifPresent: [ :value | visited := value ] ifAbsent: [ visited := true ].
+	self assert: visited = 'world'.
+
+	d at: 'buy' ifPresent: [ :value | visited := value ] ifAbsent: [ visited := true ].
+	self assert: visited.
+!
+
 testKeys
 	| d |