Ahh, that's smart. A much more elegant solution, I wish I had thought of this 
before. Well, now I can use this idea to clean up some of my code. :)

Subject: Re: attribute access among multiple windows
From: [email protected]
To: [email protected]
Date: Mon, 6 Jul 2009 20:45:52 -0700

Hey - thanks for the reply. At some point I was goofing around with things and 
forgot to put the curly brackets and para back in - good catch. In any case, 
your analysis of it gave me another idea for a solution

  button "clear" do

    debug @win.stack1.class
    @win.stack1.append {[email protected] "yet another"}
  end

That way no messy global variables or anything nor any outside window manager. 
:)

Again, thanks for your help.


Chris



On Mon, Jul 6, 2009 at 7:04 PM, Ehsanul Hoque <[email protected]> wrote:



Your idea is indeed clever in my opinion, but I'm just a ruby noob. Now let's 
see how one might massage the results you want.

The real issue is with your append statement. First off, you should put that 
statement after a call to para, and inside a block, like so:



@win.stack1.append { para "yet another" }



But this will give you a seemingly strange result. The para will appear in the 
original window. I don't know the exact route it takes to get there, but you 
should read the Shoes => Rules section of the shoes manual to get an idea of 
why this happens. I'll try to explain in brief here. Basically, some way or 
other, the para call is sent to "self" which in this case is the window you 
create with Shoes.app. Anywhere inside the Shoes.app block, self is the app 
object, and all method calls get directed to self. When you use a @stack.append 
block, self isn't changed, but shoes has some "magic", or dynamic code rather, 
that makes sure the para that gets sent to the app object does indeed end up in 
the stack you want to append to. Now, in this case you're calling append on a 
stack in another app object, which I suppose shoes isn't made to deal with. 
Thus, the para just gets sent to self (the main app object), and shows up in 
your main window.




Ok, perhaps not that brief. In any case, to solve the issue of manipulating an 
stack from outside the app object (like from another class or just another app 
object as in this case), _why has provided, in his infinite wisdom, an app() 
method for every slot (and maybe every element, but you'll have to check the 
manual to verify). What this app() method does is change self to the correct 
app object for the slot/element(?) you call app() on. And then, you can proceed 
to use whatever methods you want on it, such as append for example. So knowing 
this, you might replace the offending line this code, which is what I did:




@win.app do



@win.stack1.append { para "yet another" }

end



And then you'll get another perhaps confusing error. It'll tell you that nil 
has no stack1 method. And more confusing still, it didn't seem to think that 
@win was nil when it applied the app() method to it. So what's going on? Well, 
you have to remember that self was changed by the app block, and @win is just 
an instance variable that is available only inside an app instance, where you 
created it. So when you change self, you no longer have access to @win 
directly. To solve this problem, I set a temporary global variable to @win, and 
refer to this variable instead of @win inside the @win.app() block. And that 
way, it all works.




Now, instead of keeping track of all this inside the Shoes.app block, you might 
want to create a class outside to manage your app objects. Mind you, you'll 
have to still use the app() method, and have all the same problems, but it's 
just cleaner to separate window management into it's own class in my opinion. 
And if you want to access your class instance's attributes when you're doing an 
append, you have to remember to make sure they're all available as global 
variables, or figure some other way to do it, because they won't be 
automatically available, even though the code is in your instance method 
definition. This has bit me a number of times. I just set up a globalize() 
instance method which allows access to all the attributes globally as 
$temp[:attribute_name].




Hmm, I've written too much already. Here's the code with the fixes, just copy 
paste:



$temp = {}

Shoes.app do

  self.class.class_eval do

    attr_accessor :tribute, :stack1

  end



  @tribute = "main app"

  button "new window" do

    @win = window :title => "new window" do



      @stack1 = stack {para "this is a paragraph"}

    end

  end



  button "clear" do

    debug @win.stack1.class

    $temp[:win] = @win

    @win.app do

      $temp[:win].stack1.append { para "yet another" }

    end

  end

end



Subject: attribute access among multiple windows

From: [email protected]

To: [email protected]

Date: Mon, 6 Jul 2009 12:12:35 -0700



Hey there - I am having trouble figuring out the best way to access attributes 
among multiple windows. What I want is a main Shoes.app window that spawns 
windows which can exchange data with the main Shoes.app window. What I would 
like to do, is somehow keep track of all of the Shoes::APP objects which belong 
to the main app and be able to access ad modify their attributes. I thought 
that I had a clever idea when I did this






Shoes.app do

  self.class.class_eval do

    attr_accessor :tribute, :stack1

  end





  @tribute = "main app"

  button "new window" do

    @win = window :title => "new window" do



      @stack1 = stack {para "this is a paragraph"}

    end



  end

  button "clear" do

    debug @win.stack1.class

    @win.stack1.append "yet another"

  end

end





When I hit the "clear" button on the main window the first time, I get



debug => Shoes::Stack

Error => undefined method `call' for nil:NilClass



The next time I hit it, I get this







debug => Shoes::Stack



Error => this slot is already being modified by an append, clear, etc

_________________________________________________________________
Insert movie times and more without leaving HotmailĀ®. 
http://windowslive.com/Tutorial/Hotmail/QuickAdd?ocid=TXT_TAGLM_WL_HM_Tutorial_QuickAdd_062009

Reply via email to