Adding a System.debug changes code behavior2019 Community Moderator ElectionWhat is a use case where one would use an SObject as a Map key?Map/Set size when sobjects are duplicatedDebug Filter option which only list System.debug statements?System.debug not appearing in logs from test methodDateTime.format() unexpected behaviorHas anybody seen this behavior? Batch jobs failing silently on CPU timeout except in certain circumstancesAutomatically Remove System.debug statements from Apex Code?Apex Subscript value not valid on second submissionUnexpected results when using a custom class as key in MapSystem.debug not showing up in salesforce trigger executionSystem.debug prints twice

If a character has darkvision, can they see through an area of nonmagical darkness filled with lightly obscuring gas?

Closed-form expression for certain product

copy and scale one figure (wheel)

Is this toilet slogan correct usage of the English language?

What prevents the use of a multi-segment ILS for non-straight approaches?

Why does the Sun have different day lengths, but not the gas giants?

Is there a name for this algorithm to calculate the concentration of a mixture of two solutions containing the same solute?

How to implement a feedback to keep the DC gain at zero for this conceptual passive filter?

On a tidally locked planet, would time be quantized?

Travelling outside the UK without a passport

What was this official D&D 3.5e Lovecraft-flavored rulebook?

Reverse int within the 32-bit signed integer range: [−2^31, 2^31 − 1]

Store Credit Card Information in Password Manager?

What is this called? Old film camera viewer?

Drawing ramified coverings with tikz

How to explain what's wrong with this application of the chain rule?

Non-trope happy ending?

Removing files under particular conditions (number of files, file age)

What was the exact wording from Ivanhoe of this advice on how to free yourself from slavery?

Open a doc from terminal, but not by its name

Creepy dinosaur pc game identification

Why Shazam when there is already Superman?

What does "Scientists rise up against statistical significance" mean? (Comment in Nature)

Can I sign legal documents with a smiley face?



Adding a System.debug changes code behavior



2019 Community Moderator ElectionWhat is a use case where one would use an SObject as a Map key?Map/Set size when sobjects are duplicatedDebug Filter option which only list System.debug statements?System.debug not appearing in logs from test methodDateTime.format() unexpected behaviorHas anybody seen this behavior? Batch jobs failing silently on CPU timeout except in certain circumstancesAutomatically Remove System.debug statements from Apex Code?Apex Subscript value not valid on second submissionUnexpected results when using a custom class as key in MapSystem.debug not showing up in salesforce trigger executionSystem.debug prints twice










3















I have the following code



Map<Account, Integer> accountsMap = new Map<Account, Integer>();
Account a = new Account();
accountsMap.put(a, 1);
a.name='Bob';
//System.debug(accountsMap);
System.debug(accountsMap.get(a));
System.assertEquals(1, accountsMap.get(a));


Debug in the sixth line shows null which is expected and next assert fails. However if I uncomment debug in the fifth line I will get the following log(note that there is no assert failure):



enter image description here



Which is a bit unexpected for me as Accounts with different fields should result in a different hash. I know that using sObjects for map keys is bad practice but still interested in how adding a debug statement can change the code behavior?



As noticed in the comments, to reproduce this you have to set the debug level for Apex to anything below FINEST. On FINEST level assert always fails.










share|improve this question
























  • if I both comment 5 and 6th debug line, assert fails. Also, if I uncomment any of the 5 or 6th line, assert fails.

    – Santanu Boral
    yesterday











  • @SantanuBoral thank you for the check. I've tried changing debug level and when I set Apex level to FINEST it also fails with all debug statements uncommented, however on lower levels (FINER/FINE/DEBUG/...) it still passes the assert.

    – Oles Malkov
    yesterday















3















I have the following code



Map<Account, Integer> accountsMap = new Map<Account, Integer>();
Account a = new Account();
accountsMap.put(a, 1);
a.name='Bob';
//System.debug(accountsMap);
System.debug(accountsMap.get(a));
System.assertEquals(1, accountsMap.get(a));


Debug in the sixth line shows null which is expected and next assert fails. However if I uncomment debug in the fifth line I will get the following log(note that there is no assert failure):



enter image description here



Which is a bit unexpected for me as Accounts with different fields should result in a different hash. I know that using sObjects for map keys is bad practice but still interested in how adding a debug statement can change the code behavior?



As noticed in the comments, to reproduce this you have to set the debug level for Apex to anything below FINEST. On FINEST level assert always fails.










share|improve this question
























  • if I both comment 5 and 6th debug line, assert fails. Also, if I uncomment any of the 5 or 6th line, assert fails.

    – Santanu Boral
    yesterday











  • @SantanuBoral thank you for the check. I've tried changing debug level and when I set Apex level to FINEST it also fails with all debug statements uncommented, however on lower levels (FINER/FINE/DEBUG/...) it still passes the assert.

    – Oles Malkov
    yesterday













3












3








3


1






I have the following code



Map<Account, Integer> accountsMap = new Map<Account, Integer>();
Account a = new Account();
accountsMap.put(a, 1);
a.name='Bob';
//System.debug(accountsMap);
System.debug(accountsMap.get(a));
System.assertEquals(1, accountsMap.get(a));


Debug in the sixth line shows null which is expected and next assert fails. However if I uncomment debug in the fifth line I will get the following log(note that there is no assert failure):



enter image description here



Which is a bit unexpected for me as Accounts with different fields should result in a different hash. I know that using sObjects for map keys is bad practice but still interested in how adding a debug statement can change the code behavior?



As noticed in the comments, to reproduce this you have to set the debug level for Apex to anything below FINEST. On FINEST level assert always fails.










share|improve this question
















I have the following code



Map<Account, Integer> accountsMap = new Map<Account, Integer>();
Account a = new Account();
accountsMap.put(a, 1);
a.name='Bob';
//System.debug(accountsMap);
System.debug(accountsMap.get(a));
System.assertEquals(1, accountsMap.get(a));


Debug in the sixth line shows null which is expected and next assert fails. However if I uncomment debug in the fifth line I will get the following log(note that there is no assert failure):



enter image description here



Which is a bit unexpected for me as Accounts with different fields should result in a different hash. I know that using sObjects for map keys is bad practice but still interested in how adding a debug statement can change the code behavior?



As noticed in the comments, to reproduce this you have to set the debug level for Apex to anything below FINEST. On FINEST level assert always fails.







apex map debug






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited yesterday







Oles Malkov

















asked yesterday









Oles MalkovOles Malkov

1,7363822




1,7363822












  • if I both comment 5 and 6th debug line, assert fails. Also, if I uncomment any of the 5 or 6th line, assert fails.

    – Santanu Boral
    yesterday











  • @SantanuBoral thank you for the check. I've tried changing debug level and when I set Apex level to FINEST it also fails with all debug statements uncommented, however on lower levels (FINER/FINE/DEBUG/...) it still passes the assert.

    – Oles Malkov
    yesterday

















  • if I both comment 5 and 6th debug line, assert fails. Also, if I uncomment any of the 5 or 6th line, assert fails.

    – Santanu Boral
    yesterday











  • @SantanuBoral thank you for the check. I've tried changing debug level and when I set Apex level to FINEST it also fails with all debug statements uncommented, however on lower levels (FINER/FINE/DEBUG/...) it still passes the assert.

    – Oles Malkov
    yesterday
















if I both comment 5 and 6th debug line, assert fails. Also, if I uncomment any of the 5 or 6th line, assert fails.

– Santanu Boral
yesterday





if I both comment 5 and 6th debug line, assert fails. Also, if I uncomment any of the 5 or 6th line, assert fails.

– Santanu Boral
yesterday













@SantanuBoral thank you for the check. I've tried changing debug level and when I set Apex level to FINEST it also fails with all debug statements uncommented, however on lower levels (FINER/FINE/DEBUG/...) it still passes the assert.

– Oles Malkov
yesterday





@SantanuBoral thank you for the check. I've tried changing debug level and when I set Apex level to FINEST it also fails with all debug statements uncommented, however on lower levels (FINER/FINE/DEBUG/...) it still passes the assert.

– Oles Malkov
yesterday










3 Answers
3






active

oldest

votes


















4















Which is a bit unexpected for me as Accounts with different fields should result in a different hash. I know that using sObjects for map keys is bad practice but still interested in how adding a debug statement can change the code behavior?




Map and Set have internal state you cannot directly observe. Internally, they look a bit like this:



class Bucket<U> 
Integer hashCode;
U[] values;

public class Map<T, U>
List<Bucket<U>> buckets = new List<Bucket<U>>();
public U put(T key, U value)
Integer hashCode = value.hashCode();
Bucket<U> temp;
for(Bucket<U> bucket: buckets)
if(bucket.hashCode == hashCode)
temp = bucket;


// hash not found, make new bucket
if(temp == null)
buckets.add(temp = new Bucket<U>());
temp.hashCode = hashCode;

for(Integer i = 0; i < temp.values.size(); i++)
if(temp.values[i].equals(value))
U result = temp.values[i];
temp.values[i] = value;
return result; // Returns old value


temp.values.add(value); // Adds new value to bucket




Of course, this isn't the actual code that happens, just sort of pseudocode. As you can see, a lot of stuff is going on under the covers.



The main point here is that if you change the value, and thus its hashCode, it will no longer be found in its original bucket, which is cached inside the map.



When you force a System.debug, the internal state of the Map is refreshed and buckets are recalculated. This can change the number of keys internally and end up with fewer total elements as well.



This occurs with both Map and Set objects. If you choose to modify the hashCode of a value for a key, you will corrupt the collection's internal state until you debug it, which fixes it.



As you've observed, this causes problems when you insert sObject records, or later modify any of their fields, or otherwise use objects that have unstable hashCode values.




Side note: Using sObject keys is not a Bad Practice™. In fact, I use this technique fairly often. sObject keys allows you to perform certain types of checks efficiently without wrapper classes. However, using this technique means you need to consciously make decisions to avoid corrupting the internal state of the collection.






share|improve this answer























  • When you force a System.debug -- this doesn't have an effect at least in this case. What OP has currently never returns value for me, which is the expected behavior at least per the documentation.

    – Jayant Das
    yesterday











  • I have the exact code as OP has with no debug statements commented and it fails as expected. Only when I switch adding the name before adding the object in map, and with all other code as-is, it works perfectly fine. I was using anonymous window.

    – Jayant Das
    yesterday











  • @JayantDas Sorry, just realized that this code in the example results in a null value. That's just how things get "lost." It's entirely possible that the map will partially or fully fix itself depending on its contents. Try adding a key where name = null, then another where name = bob, then change the account where name = null to name = bob, and then debug. You'll see a different behavior.

    – sfdcfox
    yesterday











  • @sfdcfox Thanks, that is what I was looking for. Now I'm just curious is there any other way to "refresh a map state" other than System.debug? I assume this can be considered as a "hack" and one should not use such things in production code? Also, you said that you are using sObjects as map keys so how do you ensure their hash is not spoiled, I assume just do not modify the key once it was put in the map? Thanks

    – Oles Malkov
    yesterday











  • @OlesMalkov (a) JSON.serialize I think also "fixes" a map/set (b) it is undocumented behavior, certain a "hack" to avoid in production, (c) I always construct a new "key" before using get/set; I make sure to never modify the original key material. See this answer for an example usage of this technique. Notice how I consider the keys immutable by always constructing new keys every time I need one.

    – sfdcfox
    yesterday


















1














UPDATE



The below answer is applicable only when the Log Level for Apex is set to FINEST.



The behavior as noted by OP does have an impact if Log Level is set anything below FINEST.




Here's my observation.



If I run the exact code you have where you are adding the Name after adding the object in Map, I never get the debug returning 1.



accountsMap.put(a, 1);
a.name='Bob';


I get it as:




08:57:25:005 USER_DEBUG [5]|DEBUG|Account:Name=Bob=null




Now, this is the expected behavior based on documentation (emphasis mine):




Be cautious when using sObjects as map keys. Key matching for sObjects is based on the comparison of all sObject field values. If one or more field values change after adding an sObject to the map, attempting to retrieve this sObject from the map returns null. This is because the modified sObject isn’t found in the map due to different field values.




Things work as expected if you will have any system.debug or not, only if you have it added as this:



a.name='Bob';
accountsMap.put(a, 1);


As noted in the documentation, exercise caution while using SObjects as keys for maps.






share|improve this answer

























  • Just because there's a warning about using them doesn't mean it's not a good practice when used appropriately.

    – sfdcfox
    yesterday











  • If you are too sure that your object does not change, then yes. But in scenario as this one where the field value was added after the key was added, it gets difficult to maintain. Good Practice anyways is a very much debated thing as far as I can say. I would rather frame practice as consideration as noted in the documentation.

    – Jayant Das
    yesterday











  • No, I'm just saying that the documentation doesn't use the word "practice" at all. It's neither a Good Practice nor Bad Practice, just that some caution must be taken when using this technique. It's the same as with C/C++'s "pointers," a lot of people say its a "bad practice" to use pointers because they can crash the code, while others, like me, simply state you shouldn't be using them if you don't know what you're doing. The technique is perfectly safe and usable as long as one understands what goes on under the hood. The Bad Practice here is using it the wrong way.

    – sfdcfox
    yesterday











  • Agreed. I actually edited the verbiage in the answer. Ah, you remind me about the pointers -- was one of my favorites :)

    – Jayant Das
    yesterday






  • 1





    @sfdcfox, if I was writing Java still (rather than Apex) I would never use a mutable object as a key in a map. This really is bad practice because you open your application up to hard-to-find and hard-to-fix bugs. It is great that the Salesforce docs actually state caution should be taken. IMHO it would have been far better if Apex could make an object used as a key in a map (including an SObject) immutable. Any subsequent attempt to write to fields of that object would immediately throw an exception and prevent difficult to trace issues occurring later. Or provide a general immutable lock.

    – Phil W
    yesterday


















0














Note that you are using SObject as a key; when used in this way the key evaluation is based on a value comparison, so the state of your SObject is important.



When you insert into the map, the SObject was in one state, but when you get the value you have already changed the state. Whilst what you are seeing seems like strange behaviour, it is (as per @Jayant Das's answer) documented. However, what you are doing is really dodgy (IMHO).



For me, it is a bad idea to use an SObject (or indeed other mutable object) as a key; a map's internal tree/bucket structure depends on the key values and changing the key value under its feet will make the map misbehave. Much as you are seeing.



You would be better off finding a different means to provide a key for the object you are managing in the map. One option is an external ID if you must manage data in the map for SObjects that have no ID (because they are new and not yet inserted). Another is to leverage a combination of other fields within the SObject that provide some unique identity and that do not change. A third option is to hold the SObjects in an array and use the index into that array as the key value.



Whatever you do, the key value for the given SObject should not be allowed to change after first use in the map.






share|improve this answer

























  • Hey Phil, thanks for your answer but as I said in my question I know that this is a bad practice. I have just used the above example as it is a good illustration of this System.debug issue and I'm not looking for any workaround.

    – Oles Malkov
    yesterday










Your Answer








StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "459"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsalesforce.stackexchange.com%2fquestions%2f254891%2fadding-a-system-debug-changes-code-behavior%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























3 Answers
3






active

oldest

votes








3 Answers
3






active

oldest

votes









active

oldest

votes






active

oldest

votes









4















Which is a bit unexpected for me as Accounts with different fields should result in a different hash. I know that using sObjects for map keys is bad practice but still interested in how adding a debug statement can change the code behavior?




Map and Set have internal state you cannot directly observe. Internally, they look a bit like this:



class Bucket<U> 
Integer hashCode;
U[] values;

public class Map<T, U>
List<Bucket<U>> buckets = new List<Bucket<U>>();
public U put(T key, U value)
Integer hashCode = value.hashCode();
Bucket<U> temp;
for(Bucket<U> bucket: buckets)
if(bucket.hashCode == hashCode)
temp = bucket;


// hash not found, make new bucket
if(temp == null)
buckets.add(temp = new Bucket<U>());
temp.hashCode = hashCode;

for(Integer i = 0; i < temp.values.size(); i++)
if(temp.values[i].equals(value))
U result = temp.values[i];
temp.values[i] = value;
return result; // Returns old value


temp.values.add(value); // Adds new value to bucket




Of course, this isn't the actual code that happens, just sort of pseudocode. As you can see, a lot of stuff is going on under the covers.



The main point here is that if you change the value, and thus its hashCode, it will no longer be found in its original bucket, which is cached inside the map.



When you force a System.debug, the internal state of the Map is refreshed and buckets are recalculated. This can change the number of keys internally and end up with fewer total elements as well.



This occurs with both Map and Set objects. If you choose to modify the hashCode of a value for a key, you will corrupt the collection's internal state until you debug it, which fixes it.



As you've observed, this causes problems when you insert sObject records, or later modify any of their fields, or otherwise use objects that have unstable hashCode values.




Side note: Using sObject keys is not a Bad Practice™. In fact, I use this technique fairly often. sObject keys allows you to perform certain types of checks efficiently without wrapper classes. However, using this technique means you need to consciously make decisions to avoid corrupting the internal state of the collection.






share|improve this answer























  • When you force a System.debug -- this doesn't have an effect at least in this case. What OP has currently never returns value for me, which is the expected behavior at least per the documentation.

    – Jayant Das
    yesterday











  • I have the exact code as OP has with no debug statements commented and it fails as expected. Only when I switch adding the name before adding the object in map, and with all other code as-is, it works perfectly fine. I was using anonymous window.

    – Jayant Das
    yesterday











  • @JayantDas Sorry, just realized that this code in the example results in a null value. That's just how things get "lost." It's entirely possible that the map will partially or fully fix itself depending on its contents. Try adding a key where name = null, then another where name = bob, then change the account where name = null to name = bob, and then debug. You'll see a different behavior.

    – sfdcfox
    yesterday











  • @sfdcfox Thanks, that is what I was looking for. Now I'm just curious is there any other way to "refresh a map state" other than System.debug? I assume this can be considered as a "hack" and one should not use such things in production code? Also, you said that you are using sObjects as map keys so how do you ensure their hash is not spoiled, I assume just do not modify the key once it was put in the map? Thanks

    – Oles Malkov
    yesterday











  • @OlesMalkov (a) JSON.serialize I think also "fixes" a map/set (b) it is undocumented behavior, certain a "hack" to avoid in production, (c) I always construct a new "key" before using get/set; I make sure to never modify the original key material. See this answer for an example usage of this technique. Notice how I consider the keys immutable by always constructing new keys every time I need one.

    – sfdcfox
    yesterday















4















Which is a bit unexpected for me as Accounts with different fields should result in a different hash. I know that using sObjects for map keys is bad practice but still interested in how adding a debug statement can change the code behavior?




Map and Set have internal state you cannot directly observe. Internally, they look a bit like this:



class Bucket<U> 
Integer hashCode;
U[] values;

public class Map<T, U>
List<Bucket<U>> buckets = new List<Bucket<U>>();
public U put(T key, U value)
Integer hashCode = value.hashCode();
Bucket<U> temp;
for(Bucket<U> bucket: buckets)
if(bucket.hashCode == hashCode)
temp = bucket;


// hash not found, make new bucket
if(temp == null)
buckets.add(temp = new Bucket<U>());
temp.hashCode = hashCode;

for(Integer i = 0; i < temp.values.size(); i++)
if(temp.values[i].equals(value))
U result = temp.values[i];
temp.values[i] = value;
return result; // Returns old value


temp.values.add(value); // Adds new value to bucket




Of course, this isn't the actual code that happens, just sort of pseudocode. As you can see, a lot of stuff is going on under the covers.



The main point here is that if you change the value, and thus its hashCode, it will no longer be found in its original bucket, which is cached inside the map.



When you force a System.debug, the internal state of the Map is refreshed and buckets are recalculated. This can change the number of keys internally and end up with fewer total elements as well.



This occurs with both Map and Set objects. If you choose to modify the hashCode of a value for a key, you will corrupt the collection's internal state until you debug it, which fixes it.



As you've observed, this causes problems when you insert sObject records, or later modify any of their fields, or otherwise use objects that have unstable hashCode values.




Side note: Using sObject keys is not a Bad Practice™. In fact, I use this technique fairly often. sObject keys allows you to perform certain types of checks efficiently without wrapper classes. However, using this technique means you need to consciously make decisions to avoid corrupting the internal state of the collection.






share|improve this answer























  • When you force a System.debug -- this doesn't have an effect at least in this case. What OP has currently never returns value for me, which is the expected behavior at least per the documentation.

    – Jayant Das
    yesterday











  • I have the exact code as OP has with no debug statements commented and it fails as expected. Only when I switch adding the name before adding the object in map, and with all other code as-is, it works perfectly fine. I was using anonymous window.

    – Jayant Das
    yesterday











  • @JayantDas Sorry, just realized that this code in the example results in a null value. That's just how things get "lost." It's entirely possible that the map will partially or fully fix itself depending on its contents. Try adding a key where name = null, then another where name = bob, then change the account where name = null to name = bob, and then debug. You'll see a different behavior.

    – sfdcfox
    yesterday











  • @sfdcfox Thanks, that is what I was looking for. Now I'm just curious is there any other way to "refresh a map state" other than System.debug? I assume this can be considered as a "hack" and one should not use such things in production code? Also, you said that you are using sObjects as map keys so how do you ensure their hash is not spoiled, I assume just do not modify the key once it was put in the map? Thanks

    – Oles Malkov
    yesterday











  • @OlesMalkov (a) JSON.serialize I think also "fixes" a map/set (b) it is undocumented behavior, certain a "hack" to avoid in production, (c) I always construct a new "key" before using get/set; I make sure to never modify the original key material. See this answer for an example usage of this technique. Notice how I consider the keys immutable by always constructing new keys every time I need one.

    – sfdcfox
    yesterday













4












4








4








Which is a bit unexpected for me as Accounts with different fields should result in a different hash. I know that using sObjects for map keys is bad practice but still interested in how adding a debug statement can change the code behavior?




Map and Set have internal state you cannot directly observe. Internally, they look a bit like this:



class Bucket<U> 
Integer hashCode;
U[] values;

public class Map<T, U>
List<Bucket<U>> buckets = new List<Bucket<U>>();
public U put(T key, U value)
Integer hashCode = value.hashCode();
Bucket<U> temp;
for(Bucket<U> bucket: buckets)
if(bucket.hashCode == hashCode)
temp = bucket;


// hash not found, make new bucket
if(temp == null)
buckets.add(temp = new Bucket<U>());
temp.hashCode = hashCode;

for(Integer i = 0; i < temp.values.size(); i++)
if(temp.values[i].equals(value))
U result = temp.values[i];
temp.values[i] = value;
return result; // Returns old value


temp.values.add(value); // Adds new value to bucket




Of course, this isn't the actual code that happens, just sort of pseudocode. As you can see, a lot of stuff is going on under the covers.



The main point here is that if you change the value, and thus its hashCode, it will no longer be found in its original bucket, which is cached inside the map.



When you force a System.debug, the internal state of the Map is refreshed and buckets are recalculated. This can change the number of keys internally and end up with fewer total elements as well.



This occurs with both Map and Set objects. If you choose to modify the hashCode of a value for a key, you will corrupt the collection's internal state until you debug it, which fixes it.



As you've observed, this causes problems when you insert sObject records, or later modify any of their fields, or otherwise use objects that have unstable hashCode values.




Side note: Using sObject keys is not a Bad Practice™. In fact, I use this technique fairly often. sObject keys allows you to perform certain types of checks efficiently without wrapper classes. However, using this technique means you need to consciously make decisions to avoid corrupting the internal state of the collection.






share|improve this answer














Which is a bit unexpected for me as Accounts with different fields should result in a different hash. I know that using sObjects for map keys is bad practice but still interested in how adding a debug statement can change the code behavior?




Map and Set have internal state you cannot directly observe. Internally, they look a bit like this:



class Bucket<U> 
Integer hashCode;
U[] values;

public class Map<T, U>
List<Bucket<U>> buckets = new List<Bucket<U>>();
public U put(T key, U value)
Integer hashCode = value.hashCode();
Bucket<U> temp;
for(Bucket<U> bucket: buckets)
if(bucket.hashCode == hashCode)
temp = bucket;


// hash not found, make new bucket
if(temp == null)
buckets.add(temp = new Bucket<U>());
temp.hashCode = hashCode;

for(Integer i = 0; i < temp.values.size(); i++)
if(temp.values[i].equals(value))
U result = temp.values[i];
temp.values[i] = value;
return result; // Returns old value


temp.values.add(value); // Adds new value to bucket




Of course, this isn't the actual code that happens, just sort of pseudocode. As you can see, a lot of stuff is going on under the covers.



The main point here is that if you change the value, and thus its hashCode, it will no longer be found in its original bucket, which is cached inside the map.



When you force a System.debug, the internal state of the Map is refreshed and buckets are recalculated. This can change the number of keys internally and end up with fewer total elements as well.



This occurs with both Map and Set objects. If you choose to modify the hashCode of a value for a key, you will corrupt the collection's internal state until you debug it, which fixes it.



As you've observed, this causes problems when you insert sObject records, or later modify any of their fields, or otherwise use objects that have unstable hashCode values.




Side note: Using sObject keys is not a Bad Practice™. In fact, I use this technique fairly often. sObject keys allows you to perform certain types of checks efficiently without wrapper classes. However, using this technique means you need to consciously make decisions to avoid corrupting the internal state of the collection.







share|improve this answer












share|improve this answer



share|improve this answer










answered yesterday









sfdcfoxsfdcfox

261k12207452




261k12207452












  • When you force a System.debug -- this doesn't have an effect at least in this case. What OP has currently never returns value for me, which is the expected behavior at least per the documentation.

    – Jayant Das
    yesterday











  • I have the exact code as OP has with no debug statements commented and it fails as expected. Only when I switch adding the name before adding the object in map, and with all other code as-is, it works perfectly fine. I was using anonymous window.

    – Jayant Das
    yesterday











  • @JayantDas Sorry, just realized that this code in the example results in a null value. That's just how things get "lost." It's entirely possible that the map will partially or fully fix itself depending on its contents. Try adding a key where name = null, then another where name = bob, then change the account where name = null to name = bob, and then debug. You'll see a different behavior.

    – sfdcfox
    yesterday











  • @sfdcfox Thanks, that is what I was looking for. Now I'm just curious is there any other way to "refresh a map state" other than System.debug? I assume this can be considered as a "hack" and one should not use such things in production code? Also, you said that you are using sObjects as map keys so how do you ensure their hash is not spoiled, I assume just do not modify the key once it was put in the map? Thanks

    – Oles Malkov
    yesterday











  • @OlesMalkov (a) JSON.serialize I think also "fixes" a map/set (b) it is undocumented behavior, certain a "hack" to avoid in production, (c) I always construct a new "key" before using get/set; I make sure to never modify the original key material. See this answer for an example usage of this technique. Notice how I consider the keys immutable by always constructing new keys every time I need one.

    – sfdcfox
    yesterday

















  • When you force a System.debug -- this doesn't have an effect at least in this case. What OP has currently never returns value for me, which is the expected behavior at least per the documentation.

    – Jayant Das
    yesterday











  • I have the exact code as OP has with no debug statements commented and it fails as expected. Only when I switch adding the name before adding the object in map, and with all other code as-is, it works perfectly fine. I was using anonymous window.

    – Jayant Das
    yesterday











  • @JayantDas Sorry, just realized that this code in the example results in a null value. That's just how things get "lost." It's entirely possible that the map will partially or fully fix itself depending on its contents. Try adding a key where name = null, then another where name = bob, then change the account where name = null to name = bob, and then debug. You'll see a different behavior.

    – sfdcfox
    yesterday











  • @sfdcfox Thanks, that is what I was looking for. Now I'm just curious is there any other way to "refresh a map state" other than System.debug? I assume this can be considered as a "hack" and one should not use such things in production code? Also, you said that you are using sObjects as map keys so how do you ensure their hash is not spoiled, I assume just do not modify the key once it was put in the map? Thanks

    – Oles Malkov
    yesterday











  • @OlesMalkov (a) JSON.serialize I think also "fixes" a map/set (b) it is undocumented behavior, certain a "hack" to avoid in production, (c) I always construct a new "key" before using get/set; I make sure to never modify the original key material. See this answer for an example usage of this technique. Notice how I consider the keys immutable by always constructing new keys every time I need one.

    – sfdcfox
    yesterday
















When you force a System.debug -- this doesn't have an effect at least in this case. What OP has currently never returns value for me, which is the expected behavior at least per the documentation.

– Jayant Das
yesterday





When you force a System.debug -- this doesn't have an effect at least in this case. What OP has currently never returns value for me, which is the expected behavior at least per the documentation.

– Jayant Das
yesterday













I have the exact code as OP has with no debug statements commented and it fails as expected. Only when I switch adding the name before adding the object in map, and with all other code as-is, it works perfectly fine. I was using anonymous window.

– Jayant Das
yesterday





I have the exact code as OP has with no debug statements commented and it fails as expected. Only when I switch adding the name before adding the object in map, and with all other code as-is, it works perfectly fine. I was using anonymous window.

– Jayant Das
yesterday













@JayantDas Sorry, just realized that this code in the example results in a null value. That's just how things get "lost." It's entirely possible that the map will partially or fully fix itself depending on its contents. Try adding a key where name = null, then another where name = bob, then change the account where name = null to name = bob, and then debug. You'll see a different behavior.

– sfdcfox
yesterday





@JayantDas Sorry, just realized that this code in the example results in a null value. That's just how things get "lost." It's entirely possible that the map will partially or fully fix itself depending on its contents. Try adding a key where name = null, then another where name = bob, then change the account where name = null to name = bob, and then debug. You'll see a different behavior.

– sfdcfox
yesterday













@sfdcfox Thanks, that is what I was looking for. Now I'm just curious is there any other way to "refresh a map state" other than System.debug? I assume this can be considered as a "hack" and one should not use such things in production code? Also, you said that you are using sObjects as map keys so how do you ensure their hash is not spoiled, I assume just do not modify the key once it was put in the map? Thanks

– Oles Malkov
yesterday





@sfdcfox Thanks, that is what I was looking for. Now I'm just curious is there any other way to "refresh a map state" other than System.debug? I assume this can be considered as a "hack" and one should not use such things in production code? Also, you said that you are using sObjects as map keys so how do you ensure their hash is not spoiled, I assume just do not modify the key once it was put in the map? Thanks

– Oles Malkov
yesterday













@OlesMalkov (a) JSON.serialize I think also "fixes" a map/set (b) it is undocumented behavior, certain a "hack" to avoid in production, (c) I always construct a new "key" before using get/set; I make sure to never modify the original key material. See this answer for an example usage of this technique. Notice how I consider the keys immutable by always constructing new keys every time I need one.

– sfdcfox
yesterday





@OlesMalkov (a) JSON.serialize I think also "fixes" a map/set (b) it is undocumented behavior, certain a "hack" to avoid in production, (c) I always construct a new "key" before using get/set; I make sure to never modify the original key material. See this answer for an example usage of this technique. Notice how I consider the keys immutable by always constructing new keys every time I need one.

– sfdcfox
yesterday













1














UPDATE



The below answer is applicable only when the Log Level for Apex is set to FINEST.



The behavior as noted by OP does have an impact if Log Level is set anything below FINEST.




Here's my observation.



If I run the exact code you have where you are adding the Name after adding the object in Map, I never get the debug returning 1.



accountsMap.put(a, 1);
a.name='Bob';


I get it as:




08:57:25:005 USER_DEBUG [5]|DEBUG|Account:Name=Bob=null




Now, this is the expected behavior based on documentation (emphasis mine):




Be cautious when using sObjects as map keys. Key matching for sObjects is based on the comparison of all sObject field values. If one or more field values change after adding an sObject to the map, attempting to retrieve this sObject from the map returns null. This is because the modified sObject isn’t found in the map due to different field values.




Things work as expected if you will have any system.debug or not, only if you have it added as this:



a.name='Bob';
accountsMap.put(a, 1);


As noted in the documentation, exercise caution while using SObjects as keys for maps.






share|improve this answer

























  • Just because there's a warning about using them doesn't mean it's not a good practice when used appropriately.

    – sfdcfox
    yesterday











  • If you are too sure that your object does not change, then yes. But in scenario as this one where the field value was added after the key was added, it gets difficult to maintain. Good Practice anyways is a very much debated thing as far as I can say. I would rather frame practice as consideration as noted in the documentation.

    – Jayant Das
    yesterday











  • No, I'm just saying that the documentation doesn't use the word "practice" at all. It's neither a Good Practice nor Bad Practice, just that some caution must be taken when using this technique. It's the same as with C/C++'s "pointers," a lot of people say its a "bad practice" to use pointers because they can crash the code, while others, like me, simply state you shouldn't be using them if you don't know what you're doing. The technique is perfectly safe and usable as long as one understands what goes on under the hood. The Bad Practice here is using it the wrong way.

    – sfdcfox
    yesterday











  • Agreed. I actually edited the verbiage in the answer. Ah, you remind me about the pointers -- was one of my favorites :)

    – Jayant Das
    yesterday






  • 1





    @sfdcfox, if I was writing Java still (rather than Apex) I would never use a mutable object as a key in a map. This really is bad practice because you open your application up to hard-to-find and hard-to-fix bugs. It is great that the Salesforce docs actually state caution should be taken. IMHO it would have been far better if Apex could make an object used as a key in a map (including an SObject) immutable. Any subsequent attempt to write to fields of that object would immediately throw an exception and prevent difficult to trace issues occurring later. Or provide a general immutable lock.

    – Phil W
    yesterday















1














UPDATE



The below answer is applicable only when the Log Level for Apex is set to FINEST.



The behavior as noted by OP does have an impact if Log Level is set anything below FINEST.




Here's my observation.



If I run the exact code you have where you are adding the Name after adding the object in Map, I never get the debug returning 1.



accountsMap.put(a, 1);
a.name='Bob';


I get it as:




08:57:25:005 USER_DEBUG [5]|DEBUG|Account:Name=Bob=null




Now, this is the expected behavior based on documentation (emphasis mine):




Be cautious when using sObjects as map keys. Key matching for sObjects is based on the comparison of all sObject field values. If one or more field values change after adding an sObject to the map, attempting to retrieve this sObject from the map returns null. This is because the modified sObject isn’t found in the map due to different field values.




Things work as expected if you will have any system.debug or not, only if you have it added as this:



a.name='Bob';
accountsMap.put(a, 1);


As noted in the documentation, exercise caution while using SObjects as keys for maps.






share|improve this answer

























  • Just because there's a warning about using them doesn't mean it's not a good practice when used appropriately.

    – sfdcfox
    yesterday











  • If you are too sure that your object does not change, then yes. But in scenario as this one where the field value was added after the key was added, it gets difficult to maintain. Good Practice anyways is a very much debated thing as far as I can say. I would rather frame practice as consideration as noted in the documentation.

    – Jayant Das
    yesterday











  • No, I'm just saying that the documentation doesn't use the word "practice" at all. It's neither a Good Practice nor Bad Practice, just that some caution must be taken when using this technique. It's the same as with C/C++'s "pointers," a lot of people say its a "bad practice" to use pointers because they can crash the code, while others, like me, simply state you shouldn't be using them if you don't know what you're doing. The technique is perfectly safe and usable as long as one understands what goes on under the hood. The Bad Practice here is using it the wrong way.

    – sfdcfox
    yesterday











  • Agreed. I actually edited the verbiage in the answer. Ah, you remind me about the pointers -- was one of my favorites :)

    – Jayant Das
    yesterday






  • 1





    @sfdcfox, if I was writing Java still (rather than Apex) I would never use a mutable object as a key in a map. This really is bad practice because you open your application up to hard-to-find and hard-to-fix bugs. It is great that the Salesforce docs actually state caution should be taken. IMHO it would have been far better if Apex could make an object used as a key in a map (including an SObject) immutable. Any subsequent attempt to write to fields of that object would immediately throw an exception and prevent difficult to trace issues occurring later. Or provide a general immutable lock.

    – Phil W
    yesterday













1












1








1







UPDATE



The below answer is applicable only when the Log Level for Apex is set to FINEST.



The behavior as noted by OP does have an impact if Log Level is set anything below FINEST.




Here's my observation.



If I run the exact code you have where you are adding the Name after adding the object in Map, I never get the debug returning 1.



accountsMap.put(a, 1);
a.name='Bob';


I get it as:




08:57:25:005 USER_DEBUG [5]|DEBUG|Account:Name=Bob=null




Now, this is the expected behavior based on documentation (emphasis mine):




Be cautious when using sObjects as map keys. Key matching for sObjects is based on the comparison of all sObject field values. If one or more field values change after adding an sObject to the map, attempting to retrieve this sObject from the map returns null. This is because the modified sObject isn’t found in the map due to different field values.




Things work as expected if you will have any system.debug or not, only if you have it added as this:



a.name='Bob';
accountsMap.put(a, 1);


As noted in the documentation, exercise caution while using SObjects as keys for maps.






share|improve this answer















UPDATE



The below answer is applicable only when the Log Level for Apex is set to FINEST.



The behavior as noted by OP does have an impact if Log Level is set anything below FINEST.




Here's my observation.



If I run the exact code you have where you are adding the Name after adding the object in Map, I never get the debug returning 1.



accountsMap.put(a, 1);
a.name='Bob';


I get it as:




08:57:25:005 USER_DEBUG [5]|DEBUG|Account:Name=Bob=null




Now, this is the expected behavior based on documentation (emphasis mine):




Be cautious when using sObjects as map keys. Key matching for sObjects is based on the comparison of all sObject field values. If one or more field values change after adding an sObject to the map, attempting to retrieve this sObject from the map returns null. This is because the modified sObject isn’t found in the map due to different field values.




Things work as expected if you will have any system.debug or not, only if you have it added as this:



a.name='Bob';
accountsMap.put(a, 1);


As noted in the documentation, exercise caution while using SObjects as keys for maps.







share|improve this answer














share|improve this answer



share|improve this answer








edited yesterday

























answered yesterday









Jayant DasJayant Das

16.9k21230




16.9k21230












  • Just because there's a warning about using them doesn't mean it's not a good practice when used appropriately.

    – sfdcfox
    yesterday











  • If you are too sure that your object does not change, then yes. But in scenario as this one where the field value was added after the key was added, it gets difficult to maintain. Good Practice anyways is a very much debated thing as far as I can say. I would rather frame practice as consideration as noted in the documentation.

    – Jayant Das
    yesterday











  • No, I'm just saying that the documentation doesn't use the word "practice" at all. It's neither a Good Practice nor Bad Practice, just that some caution must be taken when using this technique. It's the same as with C/C++'s "pointers," a lot of people say its a "bad practice" to use pointers because they can crash the code, while others, like me, simply state you shouldn't be using them if you don't know what you're doing. The technique is perfectly safe and usable as long as one understands what goes on under the hood. The Bad Practice here is using it the wrong way.

    – sfdcfox
    yesterday











  • Agreed. I actually edited the verbiage in the answer. Ah, you remind me about the pointers -- was one of my favorites :)

    – Jayant Das
    yesterday






  • 1





    @sfdcfox, if I was writing Java still (rather than Apex) I would never use a mutable object as a key in a map. This really is bad practice because you open your application up to hard-to-find and hard-to-fix bugs. It is great that the Salesforce docs actually state caution should be taken. IMHO it would have been far better if Apex could make an object used as a key in a map (including an SObject) immutable. Any subsequent attempt to write to fields of that object would immediately throw an exception and prevent difficult to trace issues occurring later. Or provide a general immutable lock.

    – Phil W
    yesterday

















  • Just because there's a warning about using them doesn't mean it's not a good practice when used appropriately.

    – sfdcfox
    yesterday











  • If you are too sure that your object does not change, then yes. But in scenario as this one where the field value was added after the key was added, it gets difficult to maintain. Good Practice anyways is a very much debated thing as far as I can say. I would rather frame practice as consideration as noted in the documentation.

    – Jayant Das
    yesterday











  • No, I'm just saying that the documentation doesn't use the word "practice" at all. It's neither a Good Practice nor Bad Practice, just that some caution must be taken when using this technique. It's the same as with C/C++'s "pointers," a lot of people say its a "bad practice" to use pointers because they can crash the code, while others, like me, simply state you shouldn't be using them if you don't know what you're doing. The technique is perfectly safe and usable as long as one understands what goes on under the hood. The Bad Practice here is using it the wrong way.

    – sfdcfox
    yesterday











  • Agreed. I actually edited the verbiage in the answer. Ah, you remind me about the pointers -- was one of my favorites :)

    – Jayant Das
    yesterday






  • 1





    @sfdcfox, if I was writing Java still (rather than Apex) I would never use a mutable object as a key in a map. This really is bad practice because you open your application up to hard-to-find and hard-to-fix bugs. It is great that the Salesforce docs actually state caution should be taken. IMHO it would have been far better if Apex could make an object used as a key in a map (including an SObject) immutable. Any subsequent attempt to write to fields of that object would immediately throw an exception and prevent difficult to trace issues occurring later. Or provide a general immutable lock.

    – Phil W
    yesterday
















Just because there's a warning about using them doesn't mean it's not a good practice when used appropriately.

– sfdcfox
yesterday





Just because there's a warning about using them doesn't mean it's not a good practice when used appropriately.

– sfdcfox
yesterday













If you are too sure that your object does not change, then yes. But in scenario as this one where the field value was added after the key was added, it gets difficult to maintain. Good Practice anyways is a very much debated thing as far as I can say. I would rather frame practice as consideration as noted in the documentation.

– Jayant Das
yesterday





If you are too sure that your object does not change, then yes. But in scenario as this one where the field value was added after the key was added, it gets difficult to maintain. Good Practice anyways is a very much debated thing as far as I can say. I would rather frame practice as consideration as noted in the documentation.

– Jayant Das
yesterday













No, I'm just saying that the documentation doesn't use the word "practice" at all. It's neither a Good Practice nor Bad Practice, just that some caution must be taken when using this technique. It's the same as with C/C++'s "pointers," a lot of people say its a "bad practice" to use pointers because they can crash the code, while others, like me, simply state you shouldn't be using them if you don't know what you're doing. The technique is perfectly safe and usable as long as one understands what goes on under the hood. The Bad Practice here is using it the wrong way.

– sfdcfox
yesterday





No, I'm just saying that the documentation doesn't use the word "practice" at all. It's neither a Good Practice nor Bad Practice, just that some caution must be taken when using this technique. It's the same as with C/C++'s "pointers," a lot of people say its a "bad practice" to use pointers because they can crash the code, while others, like me, simply state you shouldn't be using them if you don't know what you're doing. The technique is perfectly safe and usable as long as one understands what goes on under the hood. The Bad Practice here is using it the wrong way.

– sfdcfox
yesterday













Agreed. I actually edited the verbiage in the answer. Ah, you remind me about the pointers -- was one of my favorites :)

– Jayant Das
yesterday





Agreed. I actually edited the verbiage in the answer. Ah, you remind me about the pointers -- was one of my favorites :)

– Jayant Das
yesterday




1




1





@sfdcfox, if I was writing Java still (rather than Apex) I would never use a mutable object as a key in a map. This really is bad practice because you open your application up to hard-to-find and hard-to-fix bugs. It is great that the Salesforce docs actually state caution should be taken. IMHO it would have been far better if Apex could make an object used as a key in a map (including an SObject) immutable. Any subsequent attempt to write to fields of that object would immediately throw an exception and prevent difficult to trace issues occurring later. Or provide a general immutable lock.

– Phil W
yesterday





@sfdcfox, if I was writing Java still (rather than Apex) I would never use a mutable object as a key in a map. This really is bad practice because you open your application up to hard-to-find and hard-to-fix bugs. It is great that the Salesforce docs actually state caution should be taken. IMHO it would have been far better if Apex could make an object used as a key in a map (including an SObject) immutable. Any subsequent attempt to write to fields of that object would immediately throw an exception and prevent difficult to trace issues occurring later. Or provide a general immutable lock.

– Phil W
yesterday











0














Note that you are using SObject as a key; when used in this way the key evaluation is based on a value comparison, so the state of your SObject is important.



When you insert into the map, the SObject was in one state, but when you get the value you have already changed the state. Whilst what you are seeing seems like strange behaviour, it is (as per @Jayant Das's answer) documented. However, what you are doing is really dodgy (IMHO).



For me, it is a bad idea to use an SObject (or indeed other mutable object) as a key; a map's internal tree/bucket structure depends on the key values and changing the key value under its feet will make the map misbehave. Much as you are seeing.



You would be better off finding a different means to provide a key for the object you are managing in the map. One option is an external ID if you must manage data in the map for SObjects that have no ID (because they are new and not yet inserted). Another is to leverage a combination of other fields within the SObject that provide some unique identity and that do not change. A third option is to hold the SObjects in an array and use the index into that array as the key value.



Whatever you do, the key value for the given SObject should not be allowed to change after first use in the map.






share|improve this answer

























  • Hey Phil, thanks for your answer but as I said in my question I know that this is a bad practice. I have just used the above example as it is a good illustration of this System.debug issue and I'm not looking for any workaround.

    – Oles Malkov
    yesterday















0














Note that you are using SObject as a key; when used in this way the key evaluation is based on a value comparison, so the state of your SObject is important.



When you insert into the map, the SObject was in one state, but when you get the value you have already changed the state. Whilst what you are seeing seems like strange behaviour, it is (as per @Jayant Das's answer) documented. However, what you are doing is really dodgy (IMHO).



For me, it is a bad idea to use an SObject (or indeed other mutable object) as a key; a map's internal tree/bucket structure depends on the key values and changing the key value under its feet will make the map misbehave. Much as you are seeing.



You would be better off finding a different means to provide a key for the object you are managing in the map. One option is an external ID if you must manage data in the map for SObjects that have no ID (because they are new and not yet inserted). Another is to leverage a combination of other fields within the SObject that provide some unique identity and that do not change. A third option is to hold the SObjects in an array and use the index into that array as the key value.



Whatever you do, the key value for the given SObject should not be allowed to change after first use in the map.






share|improve this answer

























  • Hey Phil, thanks for your answer but as I said in my question I know that this is a bad practice. I have just used the above example as it is a good illustration of this System.debug issue and I'm not looking for any workaround.

    – Oles Malkov
    yesterday













0












0








0







Note that you are using SObject as a key; when used in this way the key evaluation is based on a value comparison, so the state of your SObject is important.



When you insert into the map, the SObject was in one state, but when you get the value you have already changed the state. Whilst what you are seeing seems like strange behaviour, it is (as per @Jayant Das's answer) documented. However, what you are doing is really dodgy (IMHO).



For me, it is a bad idea to use an SObject (or indeed other mutable object) as a key; a map's internal tree/bucket structure depends on the key values and changing the key value under its feet will make the map misbehave. Much as you are seeing.



You would be better off finding a different means to provide a key for the object you are managing in the map. One option is an external ID if you must manage data in the map for SObjects that have no ID (because they are new and not yet inserted). Another is to leverage a combination of other fields within the SObject that provide some unique identity and that do not change. A third option is to hold the SObjects in an array and use the index into that array as the key value.



Whatever you do, the key value for the given SObject should not be allowed to change after first use in the map.






share|improve this answer















Note that you are using SObject as a key; when used in this way the key evaluation is based on a value comparison, so the state of your SObject is important.



When you insert into the map, the SObject was in one state, but when you get the value you have already changed the state. Whilst what you are seeing seems like strange behaviour, it is (as per @Jayant Das's answer) documented. However, what you are doing is really dodgy (IMHO).



For me, it is a bad idea to use an SObject (or indeed other mutable object) as a key; a map's internal tree/bucket structure depends on the key values and changing the key value under its feet will make the map misbehave. Much as you are seeing.



You would be better off finding a different means to provide a key for the object you are managing in the map. One option is an external ID if you must manage data in the map for SObjects that have no ID (because they are new and not yet inserted). Another is to leverage a combination of other fields within the SObject that provide some unique identity and that do not change. A third option is to hold the SObjects in an array and use the index into that array as the key value.



Whatever you do, the key value for the given SObject should not be allowed to change after first use in the map.







share|improve this answer














share|improve this answer



share|improve this answer








edited yesterday

























answered yesterday









Phil WPhil W

481210




481210












  • Hey Phil, thanks for your answer but as I said in my question I know that this is a bad practice. I have just used the above example as it is a good illustration of this System.debug issue and I'm not looking for any workaround.

    – Oles Malkov
    yesterday

















  • Hey Phil, thanks for your answer but as I said in my question I know that this is a bad practice. I have just used the above example as it is a good illustration of this System.debug issue and I'm not looking for any workaround.

    – Oles Malkov
    yesterday
















Hey Phil, thanks for your answer but as I said in my question I know that this is a bad practice. I have just used the above example as it is a good illustration of this System.debug issue and I'm not looking for any workaround.

– Oles Malkov
yesterday





Hey Phil, thanks for your answer but as I said in my question I know that this is a bad practice. I have just used the above example as it is a good illustration of this System.debug issue and I'm not looking for any workaround.

– Oles Malkov
yesterday

















draft saved

draft discarded
















































Thanks for contributing an answer to Salesforce Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsalesforce.stackexchange.com%2fquestions%2f254891%2fadding-a-system-debug-changes-code-behavior%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

getting Checkpoint VPN SSL Network Extender working in the command lineHow to connect to CheckPoint VPN on Ubuntu 18.04LTS?Will the Linux ( red-hat ) Open VPNC Client connect to checkpoint or nortel VPN gateways?VPN client for linux machine + support checkpoint gatewayVPN SSL Network Extender in FirefoxLinux Checkpoint SNX tool configuration issuesCheck Point - Connect under Linux - snx + OTPSNX VPN Ububuntu 18.XXUsing Checkpoint VPN SSL Network Extender CLI with certificateVPN with network manager (nm-applet) is not workingWill the Linux ( red-hat ) Open VPNC Client connect to checkpoint or nortel VPN gateways?VPN client for linux machine + support checkpoint gatewayImport VPN config files to NetworkManager from command lineTrouble connecting to VPN using network-manager, while command line worksStart a VPN connection with PPTP protocol on command linestarting a docker service daemon breaks the vpn networkCan't connect to vpn with Network-managerVPN SSL Network Extender in FirefoxUsing Checkpoint VPN SSL Network Extender CLI with certificate

대한민국 목차 국명 지리 역사 정치 국방 경제 사회 문화 국제 순위 관련 항목 각주 외부 링크 둘러보기 메뉴북위 37° 34′ 08″ 동경 126° 58′ 36″ / 북위 37.568889° 동경 126.976667°  / 37.568889; 126.976667ehThe Korean Repository문단을 편집문단을 편집추가해Clarkson PLC 사Report for Selected Countries and Subjects-Korea“Human Development Index and its components: P.198”“http://www.law.go.kr/%EB%B2%95%EB%A0%B9/%EB%8C%80%ED%95%9C%EB%AF%BC%EA%B5%AD%EA%B5%AD%EA%B8%B0%EB%B2%95”"한국은 국제법상 한반도 유일 합법정부 아니다" - 오마이뉴스 모바일Report for Selected Countries and Subjects: South Korea격동의 역사와 함께한 조선일보 90년 : 조선일보 인수해 혁신시킨 신석우, 임시정부 때는 '대한민국' 국호(國號) 정해《우리가 몰랐던 우리 역사: 나라 이름의 비밀을 찾아가는 역사 여행》“남북 공식호칭 ‘남한’‘북한’으로 쓴다”“Corea 대 Korea, 누가 이긴 거야?”국내기후자료 - 한국[김대중 前 대통령 서거] 과감한 구조개혁 'DJ노믹스'로 최단기간 환란극복 :: 네이버 뉴스“이라크 "韓-쿠르드 유전개발 MOU 승인 안해"(종합)”“해외 우리국민 추방사례 43%가 일본”차기전차 K2'흑표'의 세계 최고 전력 분석, 쿠키뉴스 엄기영, 2007-03-02두산인프라, 헬기잡는 장갑차 'K21'...내년부터 공급, 고뉴스 이대준, 2008-10-30과거 내용 찾기mk 뉴스 - 구매력 기준으로 보면 한국 1인당 소득 3만弗과거 내용 찾기"The N-11: More Than an Acronym"Archived조선일보 최우석, 2008-11-01Global 500 2008: Countries - South Korea“몇년째 '시한폭탄'... 가계부채, 올해는 터질까”가구당 부채 5000만원 처음 넘어서“‘빚’으로 내몰리는 사회.. 위기의 가계대출”“[경제365] 공공부문 부채 급증…800조 육박”“"소득 양극화 다소 완화...불평등은 여전"”“공정사회·공생발전 한참 멀었네”iSuppli,08年2QのDRAMシェア・ランキングを発表(08/8/11)South Korea dominates shipbuilding industry | Stock Market News & Stocks to Watch from StraightStocks한국 자동차 생산, 3년 연속 세계 5위자동차수출 '현대-삼성 웃고 기아-대우-쌍용은 울고' 과거 내용 찾기동반성장위 창립 1주년 맞아Archived"중기적합 3개업종 합의 무시한 채 선정"李대통령, 사업 무분별 확장 소상공인 생계 위협 질타삼성-LG, 서민업종인 빵·분식사업 잇따라 철수상생은 뒷전…SSM ‘몸집 불리기’ 혈안Archived“경부고속도에 '아시안하이웨이' 표지판”'철의 실크로드' 앞서 '말(言)의 실크로드'부터, 프레시안 정창현, 2008-10-01“'서울 지하철은 안전한가?'”“서울시 “올해 안에 모든 지하철역 스크린도어 설치””“부산지하철 1,2호선 승강장 안전펜스 설치 완료”“전교조, 정부 노조 통계서 처음 빠져”“[Weekly BIZ] 도요타 '제로 이사회'가 리콜 사태 불러들였다”“S Korea slams high tuition costs”““정치가 여론 양극화 부채질… 합리주의 절실””“〈"`촛불집회'는 민주주의의 질적 변화 상징"〉”““촛불집회가 민주주의 왜곡 초래””“국민 65%, "한국 노사관계 대립적"”“한국 국가경쟁력 27위‥노사관계 '꼴찌'”“제대로 형성되지 않은 대한민국 이념지형”“[신년기획-갈등의 시대] 갈등지수 OECD 4위…사회적 손실 GDP 27% 무려 300조”“2012 총선-대선의 키워드는 '국민과 소통'”“한국 삶의 질 27위, 2000년과 2008년 연속 하위권 머물러”“[해피 코리아] 행복점수 68점…해외 평가선 '낙제점'”“한국 어린이·청소년 행복지수 3년 연속 OECD ‘꼴찌’”“한국 이혼율 OECD중 8위”“[통계청] 한국 이혼율 OECD 4위”“오피니언 [이렇게 생각한다] `부부의 날` 에 돌아본 이혼율 1위 한국”“Suicide Rates by Country, Global Health Observatory Data Repository.”“1. 또 다른 차별”“오피니언 [편집자에게] '왕따'와 '패거리 정치' 심리는 닮은꼴”“[미래한국리포트] 무한경쟁에 빠진 대한민국”“대학생 98% "외모가 경쟁력이라는 말 동의"”“특급호텔 웨딩·200만원대 유모차… "남보다 더…" 호화病, 고질병 됐다”“[스트레스 공화국] ① 경쟁사회, 스트레스 쌓인다”““매일 30여명 자살 한국, 의사보다 무속인에…””“"자살 부르는 '우울증', 환자 중 85% 치료 안 받아"”“정신병원을 가다”“대한민국도 ‘묻지마 범죄’,안전지대 아니다”“유엔 "학생 '성적 지향'에 따른 차별 금지하라"”“유엔아동권리위원회 보고서 및 번역본 원문”“고졸 성공스토리 담은 '제빵왕 김탁구' 드라마 나온다”“‘빛 좋은 개살구’ 고졸 취업…실습 대신 착취”원본 문서“정신건강, 사회적 편견부터 고쳐드립니다”‘소통’과 ‘행복’에 목 마른 사회가 잠들어 있던 ‘심리학’ 깨웠다“[포토] 사유리-곽금주 교수의 유쾌한 심리상담”“"올해 한국인 평균 영화관람횟수 세계 1위"(종합)”“[게임연중기획] 게임은 문화다-여가활동 1순위 게임”“영화속 ‘영어 지상주의’ …“왠지 씁쓸한데””“2월 `신문 부수 인증기관` 지정..방송법 후속작업”“무료신문 성장동력 ‘차별성’과 ‘갈등해소’”대한민국 국회 법률지식정보시스템"Pew Research Center's Religion & Public Life Project: South Korea"“amp;vwcd=MT_ZTITLE&path=인구·가구%20>%20인구총조사%20>%20인구부문%20>%20 총조사인구(2005)%20>%20전수부문&oper_YN=Y&item=&keyword=종교별%20인구& amp;lang_mode=kor&list_id= 2005년 통계청 인구 총조사”원본 문서“한국인이 좋아하는 취미와 운동 (2004-2009)”“한국인이 좋아하는 취미와 운동 (2004-2014)”Archived“한국, `부분적 언론자유국' 강등〈프리덤하우스〉”“국경없는기자회 "한국, 인터넷감시 대상국"”“한국, 조선산업 1위 유지(S. Korea Stays Top Shipbuilding Nation) RZD-Partner Portal”원본 문서“한국, 4년 만에 ‘선박건조 1위’”“옛 마산시,인터넷속도 세계 1위”“"한국 초고속 인터넷망 세계1위"”“인터넷·휴대폰 요금, 외국보다 훨씬 비싸”“한국 관세행정 6년 연속 세계 '1위'”“한국 교통사고 사망자 수 OECD 회원국 중 2위”“결핵 후진국' 한국, 환자가 급증한 이유는”“수술은 신중해야… 자칫하면 생명 위협”대한민국분류대한민국의 지도대한민국 정부대표 다국어포털대한민국 전자정부대한민국 국회한국방송공사about korea and information korea브리태니커 백과사전(한국편)론리플래닛의 정보(한국편)CIA의 세계 정보(한국편)마리암 부디아 (Mariam Budia),『한국: 하늘이 내린 한 폭의 그림』, 서울: 트랜스라틴 19호 (2012년 3월)대한민국ehehehehehehehehehehehehehehWorldCat132441370n791268020000 0001 2308 81034078029-6026373548cb11863345f(데이터)00573706ge128495

Cannot Extend partition with GParted The 2019 Stack Overflow Developer Survey Results Are In Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 17/18, 2019 at 00:00UTC (8:00pm US/Eastern) 2019 Community Moderator Election ResultsCan't increase partition size with GParted?GParted doesn't recognize the unallocated space after my current partitionWhat is the best way to add unallocated space located before to Ubuntu 12.04 partition with GParted live?I can't figure out how to extend my Arch home partition into free spaceGparted Linux Mint 18.1 issueTrying to extend but swap partition is showing as Unknown in Gparted, shows proper from fdiskRearrange partitions in gparted to extend a partitionUnable to extend partition even though unallocated space is next to it using GPartedAllocate free space to root partitiongparted: how to merge unallocated space with a partition