Re: operation on module arguments




Brooks Moses wrote:
Richard E Maine wrote:
<gottoomanyaccounts@xxxxxxxxx> wrote:
Actually, before I posted the question, I was reading Fortran 90/95
Explained, Ch5.5. One of examples is show the interface operation
operating a derived type, but, well, I didn't quite get it. I will be
happy to know any method that enables me get rid of manual updating. I
will try my best to stay cool. -_-

I was attempting to be humorous. There is absolutely no way that you
would really want to do this. It would probably take thousands of lines
of code, depending on how thorough you wanted to be. That's if it can
actually be made to work as you'd want, which would take a bit of work
to figure out for sure. It was more of a random thought about a possible
trick than a serious, considered answer. In the unlikely case that you
actually do want to do as much work as would be required, then...
well... I'm afraid that I don't. :-( It would be a lot of work even
thinking through all the potential issues, much less explaining it to
someone else. More work than I'm willing to put into it. Sorry.

It's only a Really Bad Idea if it includes the attempt to make a and b
usable as if they were simple reals. Otherwise, it's just a Not
Especially Good Idea, I think. The following should work:

module foo
implicit none
private

type foo_type
real, private :: value
end type

type(foo_type), public :: a, b
real, public :: c

interface, public assignment(=)
module procedure foo_type_assign
end interface

interface, public getvalue
module procedure foo_type_getvalue
end interface
contains

subroutine foo_type_assign(out,in)
real, intent(in) :: in
type(foo_type), intent(out) :: out
out%value = in
c = a%value + b%value
end subroutine

function foo_type_getvalue(in) result(out)
type(foo_type), intent(in) :: in
real :: out
out = in%value
end function
end module

program main
use foo
implicit none
a = 1.0
b = 9.0
write(*,*) getvalue(a), getvalue(b)
write(*,*) c
end program


Note, though, that this doesn't protect against people writing to c.
And it's also using a fair bit of private declarations that prevent
direct assignments to a%value and b%value, and also prevent anything
other than a and b being declared as type(foo_type). This is untested,
and it's probably full of syntax errors and stuff, but it should convey
the general idea.

Note, also, that this means that you cannot ever use a and b directly
for much of anything; you have to use getvalue(a) and getvalue(b)
instead. I'm not at all sure that this is an improvement over the
version with seta() and geta() functions that I described earlier, or an
improvement over having c be a function rather than a variable.

This is certainly one of the solutions. I have another idea, which is
probably shorter.
That is write a module surbroutine called name_update that updates all
the variables defined in the module, and "name" is the name of the
module.

module foo
implicit none
real :: a, b, c
integer :: ia, ib, ic
.... ! other variable declarations

contains
subroutine foo_update
inplicit none
c= a + b
ia = ib*ic
.... ! other relations you want

return
end subroutine foo_update
===================================
program main
use foo
implicit none

a= 1.0; b= 5.0
ib= 5; ic=5;
call foo_update
write(*,*)c, ia

.......

read(*,*)a
read(*,*)ib
call foo_update
write(*,*)c, ia
......
end program
====================================

If you always put an module subroutine called modulename_update in the
module. Whenever you know there are changes happening on the variables
in the module, make a call modulename_update. This is probably more
sysmetamic and general. However note that, _only_ call
modulename_update when the variables that appear on the RIGHT sides in
the module subroutine modulename_update are modified. Otherwise you
will overwrite the modification if they appear on the left sides, which
is apparently not what we want.

--

.



Relevant Pages