pikelang / Pike

Pike is a dynamic programming language with a syntax similar to Java and C. It is simple to learn, does not require long compilation passes and has powerful built-in data types allowing simple and really fast data manipulation.
http://pike.lysator.liu.se/
Other
194 stars 34 forks source link

Using `copy_value` won't work as expected. #21

Closed TheOnlyArtz closed 5 years ago

TheOnlyArtz commented 5 years ago

Hey, I'm trying to use copy_value method.

  void guildMemberUpdate(mapping data) {
    Guild guild = client.guilds->get(data.guild_id);
    if (!guild) return;

    GuildMember cached = guild.members->get(data.user.id);
    if (!cached) return;

    GuildMember newMember = copy_value(cached);

    newMember.nickname = data.nick; // This line updates the cached one!
    // I don't see how copy_value should work other than cloning values so you can manipulate them
    // in a way that it won't affect the original value.

    write("%O -> %O", cached.nickname, newMember.nickname);
    // "new" -> "new"
  }
agehall commented 5 years ago

No, I’d say it works exactly as expected.

It clones your object but it does not handle any internals of your object, so all the data within the clone will be the same. I think copy_value() was mostly designed to handle deep copying of arrays, multisets and mappings, not cloning generic objects.

If you want to create clones of your own objects, you are better off implementing a constructor that can take another object as a parameter and then copy data yourself.

However, I would say that the code you show below is flawed - if you actually clone an object and update data in it, what happens to other pieces of code that has references to the older object? Are you sure you don’t want the updates to be reflected there as well?

On 29 Dec 2018, at 19:18, Amit Katz notifications@github.com wrote:

Hey, I'm trying to use copy_value https://pike.lysator.liu.se/generated/manual/modref/ex/predef_3A_3A/copy_value.html method.

void guildMemberUpdate(mapping data) { Guild guild = client.guilds->get(data.guild_id); if (!guild) return;

GuildMember cached = guild.members->get(data.user.id);
if (!cached) return;

GuildMember newMember = copy_value(cached);

newMember.nickname = data.nick; // This line updates the cached one!
// I don't see how copy_value should work other than cloning values so you can manipulate them
// in a way that it won't affect the original value.

write("%O -> %O", cached.nickname, newMember.nickname);
// "new" -> "new"

} — You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/pikelang/Pike/issues/21, or mute the thread https://github.com/notifications/unsubscribe-auth/ABHYK990MMh8nsJ8PH4d7ZxY8Yt2cJ2gks5u97HhgaJpZM4Zkqg5.

TheOnlyArtz commented 5 years ago

I'm sure I don't want the updates to be reflected there as well since I want to return the new object data next to the cached one