Question

I just started using Shoes and i know a lille bit of ruby but there is something i quite dont understand with the objects and constructor.

I learned to create objects this way:

@obj = SomeClass.new(:someParameter => 3)

Now Shoes want me to create objects this way:

Shoes.app do

     @shape = star(points: 5)

     motion do |left, top|
     @shape.move left, top
     end

end

Here is an other example:

require 'shoes'

class ListCell < Shoes::Widget
      def initialize
           stack :margin_left => 30, :top => 30  do

           line 50, 100, 200, 200

           end
      end
end

Shoes.app :width => 500, :height => 400  do

     stack  do
         @line = list_cell   
     end

end

Why is there a .new missing? Why does shoes use the syntax with the colon to pass parameter in the first example?

In the second example i create a ListCell object but I use the syntax list_cell without the new. Why does this behave like this?

This is maybe a very basic question, but i am trying to learn ruby and i have VB.Net/Java background and some things are just wierd and not very usual to me. The syntax is confusing me.

Was it helpful?

Solution 2

Class methods

Shoes.app do is not creating an instance, this is calling a class method.

This allows to call a method directly on a class, without having to instantiate it.

class Foo
  def self.hello
    puts "hello"
  end
end

Foo.hello # outputs "hello"

Block parameter

The block form may confuse you, but it's an other ruby idiom that allows to pass chunk of logic to a method :

def yell( message, &block )
  block.call( message.upcase )
end

yell( 'hello' ) do |message|
  puts message
end
# outputs "HELLO"

DSL

Finally, there's a special form of block parameter often used to have good looking configuration : blocks that are evaluated in an other context.

When you call a block like in the previous example, the code inside blocks won't be able to access any private method or variable from the class where it's called ; it can only access what is in the scope of where the block was declared.

You can change that using #instance_eval :

class Foo
  def config( &block )
    instance_eval &block
  end

  def write!
    # perform some writing
  end
end

foo = Foo.new
foo.config do
  write! # this will work
end

So, basically, your shoes are doing a combination of those three concepts :)

This is not instantiating a class (although it probably does so behind the hood) and you don't especially need that, just use initialization as you are used to.

OTHER TIPS

It is just a DSL. Those methods like star will call .new under the hood.

The colon syntax is just an alternative hash syntax introduced in Ruby 1.9.3:

{ :a => :b }
{ a: :b }

These two lines do the same thing.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top