How to use classes in Shoes?
I'm not too familiar with Shoes, but the problem you're likely having here is that you're trying to call a method called para
on the Post
class, and no such method exists.
When you call Shoes.app do ...
, I suspect Shoes is changing the current execution context to one that includes those methods. That is, you should expect this to work:
Shoes.app do
para "The author of all posts is Jimmy"
end
This is equivalent to:
Shoes.app do
self.para("The author of all posts is Jimmy")
end
When you call Post.print_author
, self
is no longer the Shoes object, but rather, is the Post class. You have a few options at that point:
Pass in the Shoes instance, and call your Shoes-specific methods on that. You should probably do it this way when you don't need any state from Post:
class Post
def self.print_author(shoes)
shoes.para "The author of all posts is Jimmy"
end
end
Shoes.app do
Post.print_author(self)
endCreate a Post class which accepts a Shoes object, so you don't have to keep passing it around. You should do it this way if Post is going to have any substantial amount of state:
class Post
def initialize(shoes)
@shoes = shoes
end
def print_author
@shoes.para "The author of all posts is Jimmy"
end
end
Shoes.app do
post = Post.new(self)
post.print_author
endYou could use a variant on the 2. option to automatically pass calls to the
@shoes
object. This starts to get into Ruby metaprogramming, which I'd recommend you avoid until you're more comfortable in Ruby, but I'm leaving it here to pique your interest:class Post
def initialize(shoes)
@shoes = shoes
end
def print_author
para "The author of all posts is Jimmy"
end
def method_missing(method, *args, &block)
@shoes.send(method, *args, &block)
end
end
Shoes.app do
post = Post.new(self)
post.print_author
end
What this does is tell Ruby "if a method isn't found on the Post instance, try sending it to the @shoes instance instead". As you can imagine, this can allow for some very nice DSLs, but you have to use it carefully, as it can make code difficult to follow if you abuse it.
How to call Shoes methods from inside an instance method?
Shoes.app { ... }
does an instance_eval of the code block. What that means is the that the body of the block gets executed as though self were an instance of Shoes
(or whatever class it is using under the hood). What you'll want to do is something like the following:
class MyClass
def initialize(app)
@app = app
end
def draw
@app.oval :top => 100, :left => 100, :radius => 30
end
end
Shoes.app {
myclass = MyClass.new(self) # passing in the app here
myclass.draw
}
How can I subclass in Shoes?
Let me guess, you're trying to do something like this:
class MyClass < Shoes
stack :width => 200 do
subtitle 'People who like ponies'
para 'TheTXI'
para 'Pesto'
para 'Einstein'
end
stack :width => -200 do
subtitle 'People who hate ponies'
para 'Hitler'
para 'Stalin'
para 'Einstein (He was bipolar)'
end
end
Well of course this doesn't work. para
, stack
, subtitle
, and so on are all instance methods, but you're trying to call them as class methods. They have to be inside an instance method, like this:
class MyClass < Shoes
url '/', :pony_list
def pony_list
stack :width => 200 do
subtitle 'People who like ponies'
para 'TheTXI'
para 'Pesto'
para 'Einstein'
end
stack :width => -200 do
subtitle 'People who hate ponies'
para 'Hitler'
para 'Stalin'
para 'Einstein (He was bipolar)'
end
end
end
Shoes.app :width => 400
See how that stuff is in the pony_list
method now? Of course, we have to make an instance call the method. How can we do that? That's why we call the url
method (which, unlike para
and its friends, actually is a class method). It sets the default url to call the pony_list
method. Remember that you have to call Shoes.app after your class definition and you're all set.
Centring a flow in Shoes
Not completely sure. What is it in your flow you are trying to centre? You can try a margin left trick as per HTML and CSS.
This gives a flow with left, centre and right justified text that remains centred in the window as it is resized:
Shoes.app do
flow do
style(:margin_left => '50%', :left => '-25%')
border blue
para "Some left justified text\n", :align => 'left'
para "Some centred text\n", :align => 'center'
para "some right justified text\n", :align => 'right'
end
end
Related Topics
Implementing Dry-Run in Ruby Script
Check If String Is Repetition of an Unknown Substring
Error: Missing Rvm Environment File After Doing Rvm Upgrade Command - Passenger 4.0.23
How to Marshal a Hash with Arrays
Need Help on Join Table, Limiting Results to Only the Resource Id
Regex to Remove the Webpage Part of a Url in Ruby
How Does Rails Know My Timezone
Undefined Method 'Click' for Nil:Nilclass (Mechanize)
Zsh Complains About Rvm _Rvm_Cleanse_Variables: Function Definition File Not Found
Get File Name and Extension in Ruby
How to Capture Terminal Arrow Keys in Ruby
Adding Nested Attributes to Devise User Model
Selenium Webdriver & Chrome Driver - Not Able to Run Chrome Driver
Define a Class Method in a Module
Mongomapper Association Skips Duplicates
How to Run Code After Ruby Kernel.Exec