help-octave
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: oct-files: assigning to substructures? assigning to multidimensional


From: Jaroslav Hajek
Subject: Re: oct-files: assigning to substructures? assigning to multidimensional structures?
Date: Sat, 28 Jun 2008 18:35:54 +0200

On Sat, Jun 28, 2008 at 5:10 PM, Olaf Till <address@hidden> wrote:
> Taking the following structure:
>
> octave-3.0.1:77> clear a
> octave-3.0.1:78> a.b1.c1 = 1;
>
> I thought that the following assignments:
>
> octave-3.0.1:79> a.b2 = 1;
> octave-3.0.1:80> a.b1.c2 = 1
> a =
> {
>  b1 =
>  {
>    c1 =  1
>    c2 =  1
>  }
>
>  b2 =  1
> }
>
> octave-3.0.1:81>
>
> could be equivalently done with the following code (passing "a" as
> first and "1" as second argument):
>
> #include <octave/oct.h>
> #include <octave/oct-map.h>
>
> DEFUN_DLD (test_assign, args, , "test assign") {
>
>  Octave_map st = args(0).map_value();
>  octave_value tmp = args(1);
>
>  st.assign("b2", tmp);
>
>  st.contents("b1")(0).map_value().assign("c2", tmp);
>
>  return octave_value (st);
>
> }
>

The problem is caused by the general Octave's philosophy of (nearly)
everything passed by value (so that you never have a problem of
dangling references), with wrappers for the actual reference-counted
objects, so that a read-only copy is as cheap as a reference.
Octave_map is no exception, and now the problem is not hard to guess:
st.contents("b1")(0).map_value() creates a *temporary copy* of the
Octave_map object inside, you then assign to this map (upon which a
clone of the original object is made),
and then it just dies away as the statement ends.

So a proper way would be (similarly to how you used the whole function):
st.contents("b1")(0) = st.contents("b1")(0).map_value().assign("c2", tmp);

To save typing (and evaluating, probably) st.contents("b1") twice, you can use:
{
  Cell& c = st.contents("b1");
  c(0) = c(0).map_value().assign("c2", tmp);
}
typicaly, only the methods or operators designed for indexed
assignment will give you a proper reference, usually you get a (cheap)
copy.

Alternatively, you can use the octave_value subsasgn method (but as
that involves constructing a std::list of octave_idx_list objects, I
doubt you would find that more convenient).







> but instead only the assignment to the top-level structure works:
>
> octave-3.0.1:81> clear a
> octave-3.0.1:82> a.b1.c1 = 1;
> octave-3.0.1:83> a = test_assign (a, 1)
> a =
> {
>  b1 =
>  {
>    c1 =  1
>  }
>
>  b2 =  1
> }
>
> octave-3.0.1:84>
>
> What am I doing wrong?
>
> A different question is how the equivalent of
>
> octave-3.0.1:...> some_structure.a(2).b = 1;
>
> can be done in an oct-file (assigning to a component of a
> multidimensional structure).
>
> Olaf
> _______________________________________________
> Help-octave mailing list
> address@hidden
> https://www.cae.wisc.edu/mailman/listinfo/help-octave
>



-- 
RNDr. Jaroslav Hajek
computing expert
Aeronautical Research and Test Institute (VZLU)
Prague, Czech Republic
url: www.highegg.matfyz.cz


reply via email to

[Prev in Thread] Current Thread [Next in Thread]