changing compiled byte arrays

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

changing compiled byte arrays

Peter Uhnak
Is this normal behavior?

cls := Object subclass: #Something.

cls compile: 'array
^ #[1 2 3 4]'.

cls new array. "#[1 2 3 4]"

cls new array at: 1 put: 55.

cls new array. "#[55 2 3 4]"

(cls>>#array) sourceCode "'array
^ #[1 2 3 4]'"


So I can permanently change the compiled byte array in the method, which is weird.

Shouldn't the behavior be either

a) don't change the original byte array

or 

b) change the source code

Thanks,
Peter
Reply | Threaded
Open this post in threaded view
|

Re: changing compiled byte arrays

Clément Béra
This is the normal behavior. You are mutating the method's literal, which becomes different. The instance is per method, so even if you do:

foo
    #[1 2 3] at: 2 put: 50.
    ^ #[1 2 3]

You get #[1 50 3], which is easy to understand in this example, but can be very tricky to understand in some cases.

I've introduced recently "read-only" objects (Object>>#isReadOnlyObject and co). I am waiting for the VM repo merge which should happen in the next few weeks to have this feature in the default Pharo VM, then I will be able to compile method literals "read-only" by default. With this feature, the #at:put: store will fail telling you that you cannot store into a read-only object, which will solve the common problem, when one does not mutate a literal on purpose.

Now as in Pharo everything is reflective, it will always be possible to mark back the literal as "writable", mutate it, and still have this behavior.

Best,
Clement


On Sat, Jul 9, 2016 at 10:22 PM, Peter Uhnák <[hidden email]> wrote:
Is this normal behavior?

cls := Object subclass: #Something.

cls compile: 'array
^ #[1 2 3 4]'.

cls new array. "#[1 2 3 4]"

cls new array at: 1 put: 55.

cls new array. "#[55 2 3 4]"

(cls>>#array) sourceCode "'array
^ #[1 2 3 4]'"


So I can permanently change the compiled byte array in the method, which is weird.

Shouldn't the behavior be either

a) don't change the original byte array

or 

b) change the source code

Thanks,
Peter

Reply | Threaded
Open this post in threaded view
|

Re: changing compiled byte arrays

Peter Uhnak
Thanks for the explanation!

I've this byte array syntax for the first time and I don't think that I will be making heavy use of it, so it shouldn't be a too big problem — since now I understand the behavior, so I can keep it in mind.

Thanks,
Peter

On Sun, Jul 10, 2016 at 7:43 AM, Clément Bera <[hidden email]> wrote:
This is the normal behavior. You are mutating the method's literal, which becomes different. The instance is per method, so even if you do:

foo
    #[1 2 3] at: 2 put: 50.
    ^ #[1 2 3]

You get #[1 50 3], which is easy to understand in this example, but can be very tricky to understand in some cases.

I've introduced recently "read-only" objects (Object>>#isReadOnlyObject and co). I am waiting for the VM repo merge which should happen in the next few weeks to have this feature in the default Pharo VM, then I will be able to compile method literals "read-only" by default. With this feature, the #at:put: store will fail telling you that you cannot store into a read-only object, which will solve the common problem, when one does not mutate a literal on purpose.

Now as in Pharo everything is reflective, it will always be possible to mark back the literal as "writable", mutate it, and still have this behavior.

Best,
Clement


On Sat, Jul 9, 2016 at 10:22 PM, Peter Uhnák <[hidden email]> wrote:
Is this normal behavior?

cls := Object subclass: #Something.

cls compile: 'array
^ #[1 2 3 4]'.

cls new array. "#[1 2 3 4]"

cls new array at: 1 put: 55.

cls new array. "#[55 2 3 4]"

(cls>>#array) sourceCode "'array
^ #[1 2 3 4]'"


So I can permanently change the compiled byte array in the method, which is weird.

Shouldn't the behavior be either

a) don't change the original byte array

or 

b) change the source code

Thanks,
Peter


Reply | Threaded
Open this post in threaded view
|

Re: changing compiled byte arrays

Clément Béra
Allright. But the problem happens for any literal you mutate, not only byte arrays.

For example this one:

foo
    #(true nil 10) at: 2 put: 50.
    ^ #(true nil 10)

Answers... #(true 50 10)

The most common problems are with Array, not ByteArray. 

Even worse, it can happen with LargeIntegers, Floats, ScaledDecimal, etc.

Hopefully read-only objects will solve most of the problems.



On Sun, Jul 10, 2016 at 10:51 AM, Peter Uhnák <[hidden email]> wrote:
Thanks for the explanation!

I've this byte array syntax for the first time and I don't think that I will be making heavy use of it, so it shouldn't be a too big problem — since now I understand the behavior, so I can keep it in mind.

Thanks,
Peter

On Sun, Jul 10, 2016 at 7:43 AM, Clément Bera <[hidden email]> wrote:
This is the normal behavior. You are mutating the method's literal, which becomes different. The instance is per method, so even if you do:

foo
    #[1 2 3] at: 2 put: 50.
    ^ #[1 2 3]

You get #[1 50 3], which is easy to understand in this example, but can be very tricky to understand in some cases.

I've introduced recently "read-only" objects (Object>>#isReadOnlyObject and co). I am waiting for the VM repo merge which should happen in the next few weeks to have this feature in the default Pharo VM, then I will be able to compile method literals "read-only" by default. With this feature, the #at:put: store will fail telling you that you cannot store into a read-only object, which will solve the common problem, when one does not mutate a literal on purpose.

Now as in Pharo everything is reflective, it will always be possible to mark back the literal as "writable", mutate it, and still have this behavior.

Best,
Clement


On Sat, Jul 9, 2016 at 10:22 PM, Peter Uhnák <[hidden email]> wrote:
Is this normal behavior?

cls := Object subclass: #Something.

cls compile: 'array
^ #[1 2 3 4]'.

cls new array. "#[1 2 3 4]"

cls new array at: 1 put: 55.

cls new array. "#[55 2 3 4]"

(cls>>#array) sourceCode "'array
^ #[1 2 3 4]'"


So I can permanently change the compiled byte array in the method, which is weird.

Shouldn't the behavior be either

a) don't change the original byte array

or 

b) change the source code

Thanks,
Peter



Reply | Threaded
Open this post in threaded view
|

Re: changing compiled byte arrays

stepharo

thanks for all the energy you put in getting non mutable objects. I will bring a nicer system.

Stef


Le 10/7/16 à 12:06, Clément Bera a écrit :
Allright. But the problem happens for any literal you mutate, not only byte arrays.

For example this one:

foo
    #(true nil 10) at: 2 put: 50.
    ^ #(true nil 10)

Answers... #(true 50 10)

The most common problems are with Array, not ByteArray. 

Even worse, it can happen with LargeIntegers, Floats, ScaledDecimal, etc.

Hopefully read-only objects will solve most of the problems.



On Sun, Jul 10, 2016 at 10:51 AM, Peter Uhnák <[hidden email]> wrote:
Thanks for the explanation!

I've this byte array syntax for the first time and I don't think that I will be making heavy use of it, so it shouldn't be a too big problem — since now I understand the behavior, so I can keep it in mind.

Thanks,
Peter

On Sun, Jul 10, 2016 at 7:43 AM, Clément Bera <[hidden email]> wrote:
This is the normal behavior. You are mutating the method's literal, which becomes different. The instance is per method, so even if you do:

foo
    #[1 2 3] at: 2 put: 50.
    ^ #[1 2 3]

You get #[1 50 3], which is easy to understand in this example, but can be very tricky to understand in some cases.

I've introduced recently "read-only" objects (Object>>#isReadOnlyObject and co). I am waiting for the VM repo merge which should happen in the next few weeks to have this feature in the default Pharo VM, then I will be able to compile method literals "read-only" by default. With this feature, the #at:put: store will fail telling you that you cannot store into a read-only object, which will solve the common problem, when one does not mutate a literal on purpose.

Now as in Pharo everything is reflective, it will always be possible to mark back the literal as "writable", mutate it, and still have this behavior.

Best,
Clement


On Sat, Jul 9, 2016 at 10:22 PM, Peter Uhnák <[hidden email]> wrote:
Is this normal behavior?

cls := Object subclass: #Something.

cls compile: 'array
^ #[1 2 3 4]'.

cls new array. "#[1 2 3 4]"

cls new array at: 1 put: 55.

cls new array. "#[55 2 3 4]"

(cls>>#array) sourceCode "'array
^ #[1 2 3 4]'"


So I can permanently change the compiled byte array in the method, which is weird.

Shouldn't the behavior be either

a) don't change the original byte array

or 

b) change the source code

Thanks,
Peter




Reply | Threaded
Open this post in threaded view
|

Re: changing compiled byte arrays

Tudor Girba-2
Thanks, indeed!

Doru


> On Jul 10, 2016, at 7:28 PM, stepharo <[hidden email]> wrote:
>
> thanks for all the energy you put in getting non mutable objects. I will bring a nicer system.
>
> Stef
>
> Le 10/7/16 à 12:06, Clément Bera a écrit :
>> Allright. But the problem happens for any literal you mutate, not only byte arrays.
>>
>> For example this one:
>>
>> foo
>>     #(true nil 10) at: 2 put: 50.
>>     ^ #(true nil 10)
>>
>> Answers... #(true 50 10)
>>
>> The most common problems are with Array, not ByteArray.
>>
>> Even worse, it can happen with LargeIntegers, Floats, ScaledDecimal, etc.
>>
>> Hopefully read-only objects will solve most of the problems.
>>
>>
>>
>> On Sun, Jul 10, 2016 at 10:51 AM, Peter Uhnák <[hidden email]> wrote:
>> Thanks for the explanation!
>>
>> I've this byte array syntax for the first time and I don't think that I will be making heavy use of it, so it shouldn't be a too big problem — since now I understand the behavior, so I can keep it in mind.
>>
>> Thanks,
>> Peter
>>
>> On Sun, Jul 10, 2016 at 7:43 AM, Clément Bera <[hidden email]> wrote:
>> This is the normal behavior. You are mutating the method's literal, which becomes different. The instance is per method, so even if you do:
>>
>> foo
>>     #[1 2 3] at: 2 put: 50.
>>     ^ #[1 2 3]
>>
>> You get #[1 50 3], which is easy to understand in this example, but can be very tricky to understand in some cases.
>>
>> I've introduced recently "read-only" objects (Object>>#isReadOnlyObject and co). I am waiting for the VM repo merge which should happen in the next few weeks to have this feature in the default Pharo VM, then I will be able to compile method literals "read-only" by default. With this feature, the #at:put: store will fail telling you that you cannot store into a read-only object, which will solve the common problem, when one does not mutate a literal on purpose.
>>
>> Now as in Pharo everything is reflective, it will always be possible to mark back the literal as "writable", mutate it, and still have this behavior.
>>
>> Best,
>> Clement
>>
>>
>> On Sat, Jul 9, 2016 at 10:22 PM, Peter Uhnák <[hidden email]> wrote:
>> Is this normal behavior?
>>
>> cls := Object subclass: #Something.
>>
>> cls compile: 'array
>> ^ #[1 2 3 4]'.
>>
>> cls new array. "#[1 2 3 4]"
>>
>> cls new array at: 1 put: 55.
>>
>> cls new array. "#[55 2 3 4]"
>>
>> (cls>>#array) sourceCode "'array
>> ^ #[1 2 3 4]'"
>>
>>
>> So I can permanently change the compiled byte array in the method, which is weird.
>>
>> Shouldn't the behavior be either
>>
>> a) don't change the original byte array
>>
>> or
>>
>> b) change the source code
>>
>> Thanks,
>> Peter
>>
>>
>>
>

--
www.tudorgirba.com
www.feenk.com

"We cannot reach the flow of things unless we let go."