Skip to content

Instantly share code, notes, and snippets.

@passenger94
Last active April 6, 2016 07:39
Show Gist options
  • Save passenger94/833d309b8599b1e14353 to your computer and use it in GitHub Desktop.
Save passenger94/833d309b8599b1e14353 to your computer and use it in GitHub Desktop.

Sometimes self is not app !!!

class SubShoes < Shoes

    url "/", :index

    def index
        para "app : #{app.inspect} ** self : #{self}"
        # self is app.slot
    end
end
Shoes.app title: "SubShoesApp"

Here

  • app is not self
  • self is app.slot
  • self has a parent slot which is the Superclass canvas
    self.parent.is_a? Shoes::Canvas #=> true

click, release callbacks inside :index must be called against self.parent NOT app or app.slot or self
keypress is happy with implicit self (redirect to app anyway ?)

There is one more slot nesting with Class-Shoes.app


class SubShoes < Shoes

    url "/", :index
    url "/elsewhere", :new_page

    def index
        visit "/elsewhere"
        # self is NOT app.slot
        
        #... some more code that runs after visit
    end
    
    def new_page
       para "app : #{app.inspect} ** self : #{self}"
       # self is app.slot
    end
end
Shoes.app title: "SubShoesApp"

Here (expert_tankspank.rb is doing it that way)

  • app is not self
  • self is NOT app.slot in :index !
  • self is app.slot in :new_page !
  • self has a parent slot
  • self.parent is not app.slot in :index and in :new_page
  • app.slot is self.parent.contents[0] in :index AND in :new_page !!

self in :index is a hidden/not accessible Shoes::Canvas
Drawing happens on :new_page not :index There is 2 different Canvas

in :new_page (like new Shoes::Canvas)

  • Root slot >> app.slot(self) >> elements

in :index (not accessible)

  • Root slot >> app.slot >> elements(not accessible)
  • What is self in :index ? i know it's a Shoes::Canvas, not app.slot, so it's probably the "hidden" one
@ccoupe
Copy link

ccoupe commented Apr 4, 2016

I think the concept is that self is set to the calling block class/object so self inside a edit_line {} is the the edit_line object

app is set to the enclosing Window aka Shoes.app or Shoes:::Window or url that contains the gui object asking for 'app.something'.
APPS is an array of known Shoes.apps each or them with different objects in the app variable. Contrived example:
In Window #1 (say it's Shoes.app) {} you've created a new Window (Shoes). APPS.size = 2. APPS[0].app and APPS[1].app point to two different objects. Self is set to which ever block is executing - maybe its inside a button block in Window 2 or in an edit_line in Window-1. In Shoes, self is transient and runtime context dependent.

I'm not sure that helps. It really is hard to describe.

@ccoupe
Copy link

ccoupe commented Apr 4, 2016

It's also difficult when you come across ruby code

Module a
   class b
      def self.doit 
      end
   end
end

Mixins are confusing.

@passenger94
Copy link
Author

It's supposed to be simple : self is app inside the Shoes.app block and in whichever new Shoes.app (window, dialog ...) we have a new self inside it . That is the consequence of instance_eval.

Shoes.app do
    edit_line "hi", width: 250 do |el|
        me = self
        el.text = me
    end
    button "hi" do
        me = self
        alert "coming from #{me}"
    end
end

everywhere self is app, didn't try every possible element but i'm guessing it's always like that.

in the case of Class/Subclass Shoes, strange things are happening, and maybe in other cases, which i'm trying to reference

Indeed in the case of the expert_tankspank.rb similar setting, above, there is a hidden slot with it's contents :

class SubShoes < Shoes
    url "/", :index
    url "/elsewhere", :new_page

    def index
        visit "/elsewhere"
        @@me = self

        background red
    end

    def new_page
       para "app : #{app.inspect} ** self : #{self.inspect}"
    end

    def self.me; @@me end
end
Shoes.app title: "SubShoesApp"

selfinclassapp

i capture self in index
it's a Canvas who's content is a background (we don't see it)
i go to the parent, from there go back to contents, note there is only one child
i go to that child and examine content, this time it's the para in new_page (we see it) !!

either there is two (SubShoes), one hidden,
either it's able to change contents depending on context ....
or ... ?

In any case when using the class way, self is not the app !!
This could make some events to not be dispatched correctly if you don't specify explicitly who you're talking to : self or app.slot or self.parent ... (first example atop)
And oh yes, app indeed knows nothing about index, me, new_page but app.slot do !!
Does this means, in the case of subClass Shoes, it is instance_eval-ed against app.slot and not app ?

Any other similar situation ?

@ccoupe
Copy link

ccoupe commented Apr 6, 2016

I think you've arrived at the same place I did when I wrote the article. self is transient (it's block local - documented) and app is a Window object. Two windows - two different app objects. Shoes.irb is a Shoes Window so has it's own app object. As I understand it (shoes/ruby.c) Canvas in a (confusing mixin module to Shoes(Types). Mixin's are not objects, they are functions/methods added to the object/class depending on how and when they got inside). Ian aka @backorder has filed several bugs because he hit the same mental roadblock. I drive on the what works now road so I'm not a lot of help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment