Another void safety question

7 messages Options
Embed this post
Permalink
Chris Saunders-4

Another void safety question

Reply Threaded More More options
Print post
Permalink
I wish to say thanks for the replies to my previous question(I chose the ~
solution).  In class EV_ENVIRONMENT `application' is detachable.  I
attempted to write a once procedure to return this.  Here is what I wrote:

 App: EV_APPLICATION
   -- Application.
  once
   Result := (create {EV_ENVIRONMENT}).application
  end

I get the error:

 2 VJAR: Source of assignment is not compatible with target. MAIN_WINDOW.App
(root_cluster) 44, 4

If the answers to my previous question included the answer to this one, I
cannot see it so ,if I'm being dumb ,my apologies.  Could someone suggest a
solution?  I would alse like to know if it is a bad idea to do this in a
multithreaded application.  I'm attempting to provide `App' because I am
calling `do_once_on_idle' several times in my project.

Regards
Chris Saunders

Jocelyn.Fiat

Re: Another void safety question

Reply Threaded More More options
Print post
Permalink
What about using the feature {EV_SHARED_APPLICATION}.ev_application:
EV_APPLICATION  which has an attached result (if you satisfy its
precondition)

(In your case, you tried to assign a detachable value
(EV_ENVIRONMENT.application) into Result which is declared as attached,
then the error.)

Note that before calling {EV_SHARED_APPLICATION}.ev_application , you
must satisfy the precondition, saying the application exists. So you
need to be sure your once will never be called before the Application
creation.

And don't forget that {EV_SHARED_APPLICATION}.ev_application return the
current application, if you have more than one (EV) application in the
same process, your "once" might not return what you expect.

About multithreaded application, that depends on your code, but usually
it is safer to do all the GUI processing in the same thread.
And this is the purpose of  do_once_on_idle, then I guess, it is ok (I
can not say more without reading your code).

However I would not use such once App (not only because of the feature
name). Whenever I would need that, I would rather inherit from
EV_SHARED_APPLICATION and then do

        if attached shared_environment.application as app then
           app.do_once_on_idle (my_action)
        end

And if you are 100% sure your application is already created at this
point, then simply use

        ev_application.do_once_on_idle (my_action)


Hope this helps,
-- Jocelyn  

Chris Saunders wrote:

> I wish to say thanks for the replies to my previous question(I chose the ~
> solution).  In class EV_ENVIRONMENT `application' is detachable.  I
> attempted to write a once procedure to return this.  Here is what I wrote:
>
>  App: EV_APPLICATION
>    -- Application.
>   once
>    Result := (create {EV_ENVIRONMENT}).application
>   end
>
> I get the error:
>
>  2 VJAR: Source of assignment is not compatible with target. MAIN_WINDOW.App
> (root_cluster) 44, 4
>
> If the answers to my previous question included the answer to this one, I
> cannot see it so ,if I'm being dumb ,my apologies.  Could someone suggest a
> solution?  I would alse like to know if it is a bad idea to do this in a
> multithreaded application.  I'm attempting to provide `App' because I am
> calling `do_once_on_idle' several times in my project.
>
> Regards
> Chris Saunders
>
>
>
> ------------------------------------
>
> Yahoo! Groups Links
>
>
>
>
>
>  

Chris Saunders-4

Re: Another void safety question

Reply Threaded More More options
Print post
Permalink
First thanks for the help Jocelyn, it has been very helpfule.  One little further question - to acquire the EV_SHARED_APPLICATION object should I just use "(create {EV_SHARED_APPLICATION}).ev_application"?  I didn't even know of the existence of EV_SHARED_APPLICATION.

Regards
Chris Saunders

  ----- Original Message -----
  From: Jocelyn
  To: [hidden email]
  Sent: Wednesday, August 26, 2009 4:03 AM
  Subject: Re: [eiffel_software] Another void safety question


    What about using the feature {EV_SHARED_APPLICATION}.ev_application:
  EV_APPLICATION which has an attached result (if you satisfy its
  precondition)

  (In your case, you tried to assign a detachable value
  (EV_ENVIRONMENT.application) into Result which is declared as attached,
  then the error.)

  Note that before calling {EV_SHARED_APPLICATION}.ev_application , you
  must satisfy the precondition, saying the application exists. So you
  need to be sure your once will never be called before the Application
  creation.

  And don't forget that {EV_SHARED_APPLICATION}.ev_application return the
  current application, if you have more than one (EV) application in the
  same process, your "once" might not return what you expect.

  About multithreaded application, that depends on your code, but usually
  it is safer to do all the GUI processing in the same thread.
  And this is the purpose of do_once_on_idle, then I guess, it is ok (I
  can not say more without reading your code).

  However I would not use such once App (not only because of the feature
  name). Whenever I would need that, I would rather inherit from
  EV_SHARED_APPLICATION and then do

  if attached shared_environment.application as app then
  app.do_once_on_idle (my_action)
  end

  And if you are 100% sure your application is already created at this
  point, then simply use

  ev_application.do_once_on_idle (my_action)

  Hope this helps,
  -- Jocelyn

  Chris Saunders wrote:
  > I wish to say thanks for the replies to my previous question(I chose the ~
  > solution). In class EV_ENVIRONMENT `application' is detachable. I
  > attempted to write a once procedure to return this. Here is what I wrote:
  >
  > App: EV_APPLICATION
  > -- Application.
  > once
  > Result := (create {EV_ENVIRONMENT}).application
  > end
  >
  > I get the error:
  >
  > 2 VJAR: Source of assignment is not compatible with target. MAIN_WINDOW.App
  > (root_cluster) 44, 4
  >
  > If the answers to my previous question included the answer to this one, I
  > cannot see it so ,if I'm being dumb ,my apologies. Could someone suggest a
  > solution? I would alse like to know if it is a bad idea to do this in a
  > multithreaded application. I'm attempting to provide `App' because I am
  > calling `do_once_on_idle' several times in my project.
  >
  > Regards
  > Chris Saunders
  >
  >
  >
  > ------------------------------------
  >
  > Yahoo! Groups Links
  >
  >
  >
  >
  >
  >



 

[Non-text portions of this message have been removed]

Peter Gummer-2

Re: Another void safety question

Reply Threaded More More options
Print post
Permalink
Chris Saunders wrote:

> ... to acquire the EV_SHARED_APPLICATION object should I just use  
> "(create {EV_SHARED_APPLICATION}).ev_application"?


Yes, or more simply, as Jocelyn said:

>  ... Whenever I would need that, I would rather inherit from
>  EV_SHARED_APPLICATION ...

- Peter Gummer
Chris Saunders-4

Re: Another void safety question

Reply Threaded More More options
Print post
Permalink
Thanks Peter, I forgot about that part of Jocelyns message.  I originally
created this project using EiffelBuild.  Should I simply replace
EV_APPLICATION with EV_SHARED_APPLICATION in the root class of the
application (seems obvious but I have never made a change to a class outside
of MAIN_WINDOW in a Vision2 application)?

I don't have a very good understanding of void safety yet so I have a
further related question.  I have come across a few places now where
detachable objects are being returned.  Is using an object test the only way
of acquiring these objects?  Also, I thought I heard that a tool was going
to be provided that converts code from non-void safe to void safe.  I'm
using EiffelStudio 6.5 but I haven't found such a tool - does one exist?

Regards
Chris Saunders

----- Original Message -----
From: Peter Gummer
To: [hidden email]
Sent: Wednesday, August 26, 2009 8:07 AM
Subject: Re: [eiffel_software] Another void safety question


  Chris Saunders wrote:

> ... to acquire the EV_SHARED_APPLICATION object should I just use
> "(create {EV_SHARED_APPLICATION}).ev_application"?

Yes, or more simply, as Jocelyn said:

> ... Whenever I would need that, I would rather inherit from
> EV_SHARED_APPLICATION ...

- Peter Gummer

 

Jocelyn.Fiat

Re: Another void safety question

Reply Threaded More More options
Print post
Permalink
Chris Saunders wrote:
> Thanks Peter, I forgot about that part of Jocelyns message.  I originally
> created this project using EiffelBuild.  Should I simply replace
> EV_APPLICATION with EV_SHARED_APPLICATION in the root class of the
> application (seems obvious but I have never made a change to a class outside
> of MAIN_WINDOW in a Vision2 application)?
>  
No, you just need to add the EV_SHARED_APPLICATION in the inherit clause
of the class where you want access to the ev_application.
But using (create {EV_SHARED_APPLICATION}).ev_application also works.
However, if you call this very often, you will create many
EV_SHARED_APPLICATION objects.
So you can also use a once to keep this object.

But adding an inheritance to EV_SHARED_APPLICATION, seems the easier way.

> I don't have a very good understanding of void safety yet so I have a
> further related question.  I have come across a few places now where
> detachable objects are being returned.  Is using an object test the only way
> of acquiring these objects?  
object test is a solution, but you can also simply use local variable

    foo: detachable FOO

    bar_1
        do
           if attached foo as l_foo then
                l_foo.do_something
           end
        end

    bar_2
        local
           l_foo: like foo
        do
           l_foo := foo
           if l_foo /= Void then
              l_foo.do_something
           end
        end

    bar_3
        local
           l_foo: like foo
        do
           l_foo := foo
           check
                 -- If you are 100% sure foo should be attached here
                 -- this check is used to tell the compiler, this l_foo
    is attached
                 -- usually you should avoid this, but sometime the
    compiler can not prove it
                foo_attached: l_foo /= Void
           end
           l_foo.do_something
        end

Quite often, when converting some non void-safe code, you are face to
the following case

       bar
          do
                -- here the code assumes `foo' is always attached
                -- sometime, it is also a weakness of the code, an
untested part and user was lucky
             foo.do_something
          end

When converting to void-safety, the code with same semantic should be

        bar_4
           local
              l_foo: like foo
           do
              l_foo := foo
              check l_foo /= Void end
              l_foo.do_something
           end

    At runtime, you will either trigger a check violation, or get a Call
on Void (if check are disable), which is not great. So use the "check
l_foo /= Void end" with care. Personally I really dislike this way to
do. So you could also do

        bar_5
           do
              if attached foo as l_foo then
                 l_foo.do_something
              else
                 check should_not_occur: False end
              end
           end

Obviously here, you should handle the "else" part with specific code,
since the original code was assuming "foo" is always attached. If you
are not 100% sure, then the else part should fix this issue.
Note, the bar_5, can be also written with local variable such as bar_2
solution.

When should you prefer local variable instead of object test local variable?
    - I would say, use local variable, when you want to reuse it in the
same feature
       for instance

              foobar
                 do
                    if attached dictionary_entry ("abc")  as l_abc then
                          l_abc.do_something
                    end
                    if attached dictionary_entry ("def")  as l_def then
                          l_def .do_something
                    end
                    if attached dictionary_entry ("ghi")  as l_ghi then
                          l_ghi .do_something
                    end
              end

       I would rather do

              foobar
                 local
                    l_entry: like dictionary_entry
                 do
                    l_entry := dictionary_entry ("abc")
                    if l_entry /= Void then
                          l_entry.do_something
                    end
                    l_entry := dictionary_entry ("def")
                    if l_entry /= Void then
                          l_entry.do_something
                    end
                    l_entry := dictionary_entry ("ghi")
                    if l_entry /= Void then
                          l_entry.do_something
                    end
              end

    The advantage of this solution is to reuse the local `l_entry'
    otherwise at runtime, in first solution, you will have 3 local
    variables, instead of just one in the later solution. This is a
    minor perfomance optimization, but we never know in critical system.
    And another big advantage, for library is that the later solution,
    can also be compiled with former compiler



I hope I was not too verbose on this question.
But you should have a look at
   
http://docs.eiffel.com/book/method/converting-existing-software-void-safety

> Also, I thought I heard that a tool was going
> to be provided that converts code from non-void safe to void safe.  I'm
> using EiffelStudio 6.5 but I haven't found such a tool - does one exist?
>  
The only tool I know for the convertion is ... the documentation
   
http://docs.eiffel.com/book/method/converting-existing-software-void-safety
I am not aware of any tool to do the conversion automatically.

Regards,
-- Jocelyn

> Regards
> Chris Saunders
>
> ----- Original Message -----
> From: Peter Gummer
> To: [hidden email]
> Sent: Wednesday, August 26, 2009 8:07 AM
> Subject: Re: [eiffel_software] Another void safety question
>
>
>   Chris Saunders wrote:
>
>  
>> ... to acquire the EV_SHARED_APPLICATION object should I just use
>> "(create {EV_SHARED_APPLICATION}).ev_application"?
>>    
>
> Yes, or more simply, as Jocelyn said:
>
>  
>> ... Whenever I would need that, I would rather inherit from
>> EV_SHARED_APPLICATION ...
>>    
>
> - Peter Gummer
>
>  
>
>
>
> ------------------------------------
>
> Yahoo! Groups Links
>
>
>
>
>
>  

Chris Saunders-4

Re: Another void safety question

Reply Threaded More More options
Print post
Permalink
I don't like to pollute the list with too many thank you notes but I consider your post to have required quite a bit of effort.  I'm certain that it will be very helpful even though I have only given it a cursory reading so far.  My thanks to you Jocelyn.

Regards
Chris Saunders


  ----- Original Message -----
  From: Jocelyn
  To: [hidden email]
  Sent: Thursday, August 27, 2009 2:39 AM
  Subject: Re: [eiffel_software] Another void safety question


    Chris Saunders wrote:
  > Thanks Peter, I forgot about that part of Jocelyns message. I originally
  > created this project using EiffelBuild. Should I simply replace
  > EV_APPLICATION with EV_SHARED_APPLICATION in the root class of the
  > application (seems obvious but I have never made a change to a class outside
  > of MAIN_WINDOW in a Vision2 application)?
  >
  No, you just need to add the EV_SHARED_APPLICATION in the inherit clause
  of the class where you want access to the ev_application.
  But using (create {EV_SHARED_APPLICATION}).ev_application also works.
  However, if you call this very often, you will create many
  EV_SHARED_APPLICATION objects.
  So you can also use a once to keep this object.

  But adding an inheritance to EV_SHARED_APPLICATION, seems the easier way.

  > I don't have a very good understanding of void safety yet so I have a
  > further related question. I have come across a few places now where
  > detachable objects are being returned. Is using an object test the only way
  > of acquiring these objects?
  object test is a solution, but you can also simply use local variable

  foo: detachable FOO

  bar_1
  do
  if attached foo as l_foo then
  l_foo.do_something
  end
  end

  bar_2
  local
  l_foo: like foo
  do
  l_foo := foo
  if l_foo /= Void then
  l_foo.do_something
  end
  end

  bar_3
  local
  l_foo: like foo
  do
  l_foo := foo
  check
  -- If you are 100% sure foo should be attached here
  -- this check is used to tell the compiler, this l_foo
  is attached
  -- usually you should avoid this, but sometime the
  compiler can not prove it
  foo_attached: l_foo /= Void
  end
  l_foo.do_something
  end

  Quite often, when converting some non void-safe code, you are face to
  the following case

  bar
  do
  -- here the code assumes `foo' is always attached
  -- sometime, it is also a weakness of the code, an
  untested part and user was lucky
  foo.do_something
  end

  When converting to void-safety, the code with same semantic should be

  bar_4
  local
  l_foo: like foo
  do
  l_foo := foo
  check l_foo /= Void end
  l_foo.do_something
  end

  At runtime, you will either trigger a check violation, or get a Call
  on Void (if check are disable), which is not great. So use the "check
  l_foo /= Void end" with care. Personally I really dislike this way to
  do. So you could also do

  bar_5
  do
  if attached foo as l_foo then
  l_foo.do_something
  else
  check should_not_occur: False end
  end
  end

  Obviously here, you should handle the "else" part with specific code,
  since the original code was assuming "foo" is always attached. If you
  are not 100% sure, then the else part should fix this issue.
  Note, the bar_5, can be also written with local variable such as bar_2
  solution.

  When should you prefer local variable instead of object test local variable?
  - I would say, use local variable, when you want to reuse it in the
  same feature
  for instance

  foobar
  do
  if attached dictionary_entry ("abc") as l_abc then
  l_abc.do_something
  end
  if attached dictionary_entry ("def") as l_def then
  l_def .do_something
  end
  if attached dictionary_entry ("ghi") as l_ghi then
  l_ghi .do_something
  end
  end

  I would rather do

  foobar
  local
  l_entry: like dictionary_entry
  do
  l_entry := dictionary_entry ("abc")
  if l_entry /= Void then
  l_entry.do_something
  end
  l_entry := dictionary_entry ("def")
  if l_entry /= Void then
  l_entry.do_something
  end
  l_entry := dictionary_entry ("ghi")
  if l_entry /= Void then
  l_entry.do_something
  end
  end

  The advantage of this solution is to reuse the local `l_entry'
  otherwise at runtime, in first solution, you will have 3 local
  variables, instead of just one in the later solution. This is a
  minor perfomance optimization, but we never know in critical system.
  And another big advantage, for library is that the later solution,
  can also be compiled with former compiler

  I hope I was not too verbose on this question.
  But you should have a look at

  http://docs.eiffel.com/book/method/converting-existing-software-void-safety

  > Also, I thought I heard that a tool was going
  > to be provided that converts code from non-void safe to void safe. I'm
  > using EiffelStudio 6.5 but I haven't found such a tool - does one exist?
  >
  The only tool I know for the convertion is ... the documentation

  http://docs.eiffel.com/book/method/converting-existing-software-void-safety
  I am not aware of any tool to do the conversion automatically.

  Regards,
  -- Jocelyn
  > Regards
  > Chris Saunders
  >
  > ----- Original Message -----
  > From: Peter Gummer
  > To: [hidden email]
  > Sent: Wednesday, August 26, 2009 8:07 AM
  > Subject: Re: [eiffel_software] Another void safety question
  >
  >
  > Chris Saunders wrote:
  >
  >
  >> ... to acquire the EV_SHARED_APPLICATION object should I just use
  >> "(create {EV_SHARED_APPLICATION}).ev_application"?
  >>
  >
  > Yes, or more simply, as Jocelyn said:
  >
  >
  >> ... Whenever I would need that, I would rather inherit from
  >> EV_SHARED_APPLICATION ...
  >>
  >
  > - Peter Gummer
  >
  >
  >
  >
  >
  > ------------------------------------
  >
  > Yahoo! Groups Links
  >
  >
  >
  >
  >
  >



 

[Non-text portions of this message have been removed]