Skip to content

Commit

Permalink
Merge pull request #1821 from arturo-lang/add-safe-get-set-overrides-…
Browse files Browse the repository at this point in the history
…for-objects

Add safe `get`/`set` overrides for custom types
  • Loading branch information
drkameleon authored Dec 7, 2024
2 parents fd8d8dc + 82f01e8 commit dbbd13a
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 6 deletions.
30 changes: 25 additions & 5 deletions src/library/Collections.nim
Original file line number Diff line number Diff line change
Expand Up @@ -696,7 +696,9 @@ proc defineLibrary*() =
"collection": {String, Block, Range, Dictionary, Object, Store, Date, Binary, Bytecode, Complex, Error, ErrorKind},
"index" : {Any}
},
attrs = NoAttrs,
attrs = {
"safe" : ({Logical}, "get value, overriding potential magic methods (only for Object values)")
},
returns = {Any},
example = """
user: #[
Expand Down Expand Up @@ -730,6 +732,13 @@ proc defineLibrary*() =
print a\real ; 1.0
print a\imaginary ; 2.0
print a\1 ; 2.0
..........
define :person [
get: method [what][
(key? this what)? -> get.safe this what ; if the key exists, return the value
-> "DEFAULT" ; otherwise, do something else
]
]
""":
#=======================================================
case xKind:
Expand Down Expand Up @@ -806,14 +815,14 @@ proc defineLibrary*() =
of String, Word, Literal:
if (let got = GetObjectKey(x, y.s, withError=false); not got.isNil):
push(got)
elif x.magic.fetch(GetM):
elif x.magic.fetch(GetM) and (not hadAttr("safe")):
mgk(@[x, y]) # value already pushed
else:
discard GetObjectKey(x, y.s) # Merely to trigger the error
else:
if (let got = GetObjectKey(x, $(y), withError=false); not got.isNil):
push(got)
elif x.magic.fetch(GetM):
elif x.magic.fetch(GetM) and (not hadAttr("safe")):
mgk(@[x, y]) # value already pushed
else:
discard GetObjectKey(x, $(y)) # Merely to trigger the error
Expand Down Expand Up @@ -1725,7 +1734,9 @@ proc defineLibrary*() =
"index" : {Any},
"value" : {Any}
},
attrs = NoAttrs,
attrs = {
"safe" : ({Logical}, "set value, overriding potential magic methods (only for Object values)")
},
returns = {Nothing},
example = """
myDict: #[
Expand All @@ -1747,6 +1758,15 @@ proc defineLibrary*() =
str\0: `x`
print str
; xello
..........
define :person [
set: method [what, value][
; do some processing...
set.safe this what value
; and actually set the value internally
]
]
""":
#=======================================================
case xKind:
Expand Down Expand Up @@ -1799,7 +1819,7 @@ proc defineLibrary*() =
of Object:
if unlikely(x.magic.fetch(ChangingM)):
mgk(@[x, y])
if (x.magic.fetch(SetM) and (y.kind in {String,Word,Literal,Label}) and (y.s notin toSeq(x.proto.fields.keys()))):
if (x.magic.fetch(SetM) and (not hadAttr("safe")) and (y.kind in {String,Word,Literal,Label}) and (y.s notin toSeq(x.proto.fields.keys()))):
mgk(@[x, y, z])
else:
case yKind:
Expand Down
2 changes: 1 addition & 1 deletion version/build
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3321
3323

0 comments on commit dbbd13a

Please sign in to comment.