You could use the eltype function, but having thought more about it, I 
think it might be easier (and more general) if you operate on the objects 
instead of the container. Something like:

@generated function modify_field{g}(x, ::Type{Val{g}}, v)
    F = fieldnames(x)
    D = Any[:(x.$f) for f in F]
    D[F .== g] = :v
    Expr(:call, symbol(x), D...)
end

macro modify_field!(ex)
    ex.head == :(=) && ex.args[1].head == :(.) || error("Invalid usage of 
@modify_field! macro")
    lhs, v = ex.args
    x, g = lhs.args
    :($(esc(x)) = modify_field($(esc(x)), Val{$g}, $v))
end

Note that modify_field doesn't actually change anything (it creates a new 
instance), the re-assignment is done by the macro, e.g.:        

immutable Immut
    intfld::Int
    isadded::Bool
end

Y = [Immut(i,false) for i = 1:10]
for i = 1:5
    @modify_field! Y[i].isadded = true
end
Y

This also allows you to use it without an array

y = Immut(1,false)
@modify_field! y.isadded = true
y

That said, I haven't done any profiling to compare speed.

-Simon


On Tuesday, 2 June 2015 03:24:51 UTC+1, [email protected] wrote:
>
> Simon,
>
> Sorry to follow up so quickly on my own post, but I'm not able to figure 
> out how to use generated functions for this purpose.  Consider:
>
>    modifyField!(a,k,Val{:isadded}, true)
>
> The generated-function routine modifyField! needs to know the base type of 
> a.  In other words, there exists some base type, say Immut, such that a is 
> an array of Immut's or a dict of Immut's or some other container, and 
> :isadded is one of the fields of Immut.  (The generator function 
> modifyField! needs to know about Immut in order to enumerate all of its 
> other  fields).
>
> I don't see how to determine this base type within the generator.  Say, 
> for example, that the type of a is Array{Immut,1}.  I was hoping that one 
> of the following introspective calls would work:
>
>     methodswith(typeof(a), setindex!, false)
>     methodswith(typeof(a), setindex!, true)
>
> but neither worked -- the first did not return any methods, whereas the 
> second returned a huge list of methods without any clear winner.  Another 
> possibility might be:
>
>     code_typed(getindex, (typeof(a), typeof(k))
>
> but I didn't know how to analyze this output for the general case; it 
> seems like determining the return value of getindex is as hard as the 
> halting problem!
>
> Thanks,
> Steve
>
>
> On Monday, June 1, 2015 at 5:57:19 PM UTC-4, Simon Byrne wrote:
>>
>> That's some impressive metaprogramming. In v0.4, you should be able to do 
>> this without the "maker" functions, using generated functions
>>
>> http://julia.readthedocs.org/en/latest/manual/metaprogramming/#generated-functions
>>
>> As far as an interface goes, I would suggest a macro, e.g. so that the 
>> user could write something like
>>
>> @modify! a[i].field = new
>>
>>
>> On Monday, 1 June 2015 03:09:29 UTC+1, [email protected] wrote:
>>>
>>> Following up on an earlier discussion that I started in this newsgroup, 
>>> I have written a small package that provides a routine to modify a field of 
>>> an immutable object in the case that the object is inside a container. 
>>>  Please refer to:
>>>
>>> https://github.com/StephenVavasis/Modifyfield.jl 
>>> <https://www.google.com/url?q=https%3A%2F%2Fgithub.com%2FStephenVavasis%2FModifyfield.jl&sa=D&sntz=1&usg=AFQjCNEMQeocqbzVy4CBDgPjAQNZhmq8Fg>
>>>
>>> Feedback is welcome.
>>>
>>>
>>>

Reply via email to