Written by

Question Rubens Silva · Mar 13, 2020

Strange behavior when using $get

Looks like the $get is actually trying to use the property getter instead of evaluating the GetAt as a method first.
Should this be considered a bug?

Comments

Peter Steiwer · Mar 13, 2020

Based on the documentation, it seems like this may be expected since $GET is expecting a variable, not a value returned from a method call. The main purpose is to protect against undefined references which a method call should never return since an empty string is different than undefined. Since the documentation mentions it accepts multidimensional object properties, it seems like it is assuming this is what the passed in reference is.

Documentation on expected values here.

0
Peter Steiwer  Mar 13, 2020 to Peter Steiwer

To add a little more to this, I would say it is basically the same as using SET vs WRITE:

SAMPLES>set person=##class(Sample.Person).%OpenId(1)
 
SAMPLES>w person.CurrentAge($h-1000)
2
SAMPLES>set person.CurrentAge($h-1000)=1
 
SET person.CurrentAge($H-1000)=1
^
<PROPERTY DOES NOT EXIST> *CurrentAge,Sample.Person

0
Ken Earl · Mar 16, 2020

Interesting question and one I hadn't considered.

If it helps, you need to think about  the type of data you are referencing as they work on different data structures:

  • $GET works on variables, arrays and global references but does not refer to object data. 
  • GetAt is a specific object function.

I cannot see any need to combine both in the same instruction, both return null if the item does not exist.

Hope this helps.
 

0
Rubens Silva  Mar 16, 2020 to Ken Earl

I cannot see any need to combine both in the same instruction, both return null if the item does not exist.

I wanted to avoid writing more than one line or having to get the value twice, e.g.

set value = array.GetAt("key")
if value = "" set value = "default"

I actually did it that way. But I could do it this way too:

set value = $select(array.GetAt("key") '= "" array.GetAt("key"), 1: "default")

But now I would be calling it twice which seemed like code smell for me.

0
Ken Earl  Mar 16, 2020 to Rubens Silva

I think you're overthinking this, either method is fine. If you are passing a key value and not searching each time then this is nothing to worry about. Sometimes doing something in 2 steps can be easier to read than a compound instruction.

0
Vitaliy Serdtsev  Mar 16, 2020 to Rubens Silva

You can do this very simply (<FONT COLOR="#0000ff">$get</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#800000">array</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#0000ff">Data</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">"key"</FONT><FONT COLOR="#000000">),</FONT><FONT COLOR="#008000">"default"</FONT><FONT COLOR="#000000">)</FONT>), for example:

<FONT COLOR="#0000ff">set </FONT><FONT COLOR="#800000">array</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#000080">##class</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008080">%ArrayOfDataTypes</FONT><FONT COLOR="#000000">).</FONT><FONT COLOR="#0000ff">%New</FONT><FONT COLOR="#000000">()

</FONT><FONT COLOR="#0000ff">write $get</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#800000">array</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#0000ff">Data</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">"oops"</FONT><FONT COLOR="#000000">),</FONT><FONT COLOR="#008000">"what?!"</FONT><FONT COLOR="#000000">),!

</FONT><FONT COLOR="#0000ff">do </FONT><FONT COLOR="#800000">array</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#0000ff">SetAt</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">"blabla"</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#008000">"oops"</FONT><FONT COLOR="#000000">)     </FONT><FONT COLOR="#0000ff">write $get</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#800000">array</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#0000ff">Data</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">"oops"</FONT><FONT COLOR="#000000">),</FONT><FONT COLOR="#008000">"what?!"</FONT><FONT COLOR="#000000">),!</FONT>

0
Rubens Silva  Mar 16, 2020 to Vitaliy Serdtsev

I can't believe I forgot about that Data property.
I just won't mark your reply as the answer because I didn't specified that I wanted to know how to do that. My bad... but thanks anyway.

0