简体   繁体   中英

How to use classes in Shoes?

I'm a somewhat beginner programmer who has a background in using Processing. I'm currently trying to make an app with Shoes, but I'm confused over how objects and classes work.

I understand that the following would run in Ruby:

class Post
    def self.print_author
      puts "The author of all posts is Jimmy"
    end
end

Post.print_author

But why won't the following run in Shoes? How would I make it run?

class Post
    def self.print_author
      para "The author of all posts is Jimmy"
    end
end

Shoes.app do
    Post.print_author
end

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:

  1. 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) end 
  2. Create 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 end 
  3. You 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.

A much simpler way to do this is to have Post provide the content, and then, in your Shoes app, render that content however you want it. Side benefit: you can re-use your Post class in another class that prints to the console.

class Post
  def self.print_author
    "The author of all posts is Jimmy"
  end
end

Shoes.app do
  para Post.print_author
end

class ConsoleApp
  def run
    puts Post.print_author
  end
end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM