From: Bam Ting on 17 Mar 2010 19:40 Hi f90 the compiler does seem to distinguish between methods from user defined types. I have two type one "has a" instance of the other. Both have a methods named Print (with different typed arguments). I want both user defined type to have the same method Print and be callable by each other. How can I do what I want? module BoxModule type Box .... end type contains subroutine Print(b) type(Box) b .... end subroutine end module module OtherModule type Other .... type(Box) b .... end type contains subroutine Print(o) ! <----------------------------- compiler doesn't like this type(Other) o .... Print(o%b) .... end subroutine end module subroutine Print(c) 1 use BoxModule 2 Error: Procedure 'print' at (1) is already defined at (2)
From: Richard Maine on 17 Mar 2010 23:40 Bam Ting <bampingting(a)gmail.com> wrote: > f90 the compiler does seem to distinguish between methods from user > defined types. I have two type one "has a" instance of the other. Both > have a methods named Print (with different typed arguments). I want > both user defined type to have the same method Print and be callable > by each other. How can I do what I want? Your terminology makes the question confusing. Fortran doesn't have "methods". It does have procedures. While procedures can bear some relationship with what are sometimes called methods, they aren't identical and you'll likely cause great confusion, both to yourself and others, if you refer to procedures as methods. The type-bound procedures introduced in f2003 are more like "methods", but that's not an f90 feature. And talking about "methods from user defined types" just makes the confusion worse. You can't define a procedure in a type - not in f90. You can, as your code does, define a type and a procedure that operates on that type in the same module. But the procedure is not in any sense "from" the type. It is from the module and happens to have an argument of the type. > module BoxModule > type Box > ... > end type > contains > subroutine Print(b) > type(Box) b > ... > end subroutine > end module > > module OtherModule > type Other > ... > type(Box) b > ... > end type > contains > subroutine Print(o) ! <----------------------------- compiler doesn't > like this > type(Other) o > ... > Print(o%b) > ... > end subroutine > end module The closest thing in f90 to what I think you are asking for is a generic procedure. You give the specific procedures all different names (perhaps something like print_box and print_other), but then put them all in a generic named print. Multiple specific procedures can share the same generic name - that's what generics are about. You cannot, however, have two specific procedures of the same name in the same scope. The compiler wouldn't know which one you are talking about; if you expect it to tell based on the argument types, well, that's what generic procedures do. That would address the problem you illustrate above, but your description hints at another problem when you talk about having them call "each other". Module USE statements cannot be recursive. That is, if module OTHER used module BOX, then module BOX cannot also use module OTHER. Your code doesn't illustrate that problem, but your description alludes to it. If indeed you do need them to be able to call each other, that can be tricky in f90. The solutions tend to be a bit awkward and involve some restructuring. -- Richard Maine | Good judgment comes from experience; email: last name at domain . net | experience comes from bad judgment. domain: summertriangle | -- Mark Twain
From: Bam Ting on 18 Mar 2010 02:02 On Mar 17, 8:40 pm, nos...(a)see.signature (Richard Maine) wrote: > Bam Ting <bampingt...(a)gmail.com> wrote: > > f90 the compiler does seem to distinguish between methods from user > > defined types. I have two type one "has a" instance of the other. Both > > have a methods named Print (with different typed arguments). I want > > both user defined type to have the same method Print and be callable > > by each other. How can I do what I want? > > Your terminology makes the question confusing. Fortran doesn't have > "methods". It does have procedures. While procedures can bear some > relationship with what are sometimes called methods, they aren't > identical and you'll likely cause great confusion, both to yourself and > others, if you refer to procedures as methods. The type-bound procedures > introduced in f2003 are more like "methods", but that's not an f90 > feature. > > And talking about "methods from user defined types" just makes the > confusion worse. You can't define a procedure in a type - not in f90. > You can, as your code does, define a type and a procedure that operates > on that type in the same module. But the procedure is not in any sense > "from" the type. It is from the module and happens to have an argument > of the type. > > > > > module BoxModule > > type Box > > ... > > end type > > contains > > subroutine Print(b) > > type(Box) b > > ... > > end subroutine > > end module > > > module OtherModule > > type Other > > ... > > type(Box) b > > ... > > end type > > contains > > subroutine Print(o) ! <----------------------------- compiler doesn't > > like this > > type(Other) o > > ... > > Print(o%b) > > ... > > end subroutine > > end module > > The closest thing in f90 to what I think you are asking for is a generic > procedure. You give the specific procedures all different names (perhaps > something like print_box and print_other), but then put them all in a > generic named print. Multiple specific procedures can share the same > generic name - that's what generics are about. You cannot, however, have > two specific procedures of the same name in the same scope. The compiler > wouldn't know which one you are talking about; if you expect it to tell > based on the argument types, well, that's what generic procedures do. > > That would address the problem you illustrate above, but your > description hints at another problem when you talk about having them > call "each other". Module USE statements cannot be recursive. That is, > if module OTHER used module BOX, then module BOX cannot also use module > OTHER. Your code doesn't illustrate that problem, but your description > alludes to it. If indeed you do need them to be able to call each other, > that can be tricky in f90. The solutions tend to be a bit awkward and > involve some restructuring. > > -- > Richard Maine | Good judgment comes from experience; > email: last name at domain . net | experience comes from bad judgment. > domain: summertriangle | -- Mark Twain Thanks for the reply! It's not recursive sorry for the confusing language. I have one type that has as its members instances of another type. I want a specialized subroutine Print associated with both types that knows how to print all of its members. In the type that contains I need to call Print on the contained instances during Print. I hope that's clearer. I'm not very good with fortran so I don't know all of the terminology. I thought the compiler should be able to differentiate between functions with different typed arguments. I guess I'm after a generic procedure. But I had hoped to keep the user defined types implementations separate and self contained where possible, eg. Box doesn't need to know anything about Other. Thanks again
From: jwm on 18 Mar 2010 02:58 On Mar 18, 12:02 am, Bam Ting <bampingt...(a)gmail.com> wrote: > I guess I'm after a generic procedure. But I had hoped to keep the > user defined types implementations separate and self contained where > possible, eg. Box doesn't need to know anything about Other. What about this: module BoxModule implicit none private type, public :: Box .... end type interface Print module procedure Print end interface public Print contains subroutine Print(b) type(Box), intent(IN) :: b .... end subroutine end module module OtherModule implicit none use BoxModule private type, public :: Other .... type(Box) :: b .... end type interface Print module procedure PrintOther end interface public Print contains subroutine PrintOther(o) type(Other), intent(IN) :: o .... call Print(o%b) .... end subroutine end module program main use OtherModule use BoxModule implicit none type(Box) :: a type(Other) :: b .... call Print(a) call Print(b) .... end program
From: Richard Maine on 18 Mar 2010 04:03 Bam Ting <bampingting(a)gmail.com> wrote: > I guess I'm after a generic procedure. But I had hoped to keep the > user defined types implementations separate and self contained where > possible, eg. Box doesn't need to know anything about Other. They don't have to know about each other to make a generic. Each separately gives the generic name to its own specific. -- Richard Maine | Good judgment comes from experience; email: last name at domain . net | experience comes from bad judgment. domain: summertriangle | -- Mark Twain
|
Pages: 1 Prev: inquire size of a file Next: Creating software Diagrams and documentation |