我刚开始使用鞋子,我知道一点点红宝石,但有些东西我对这些对象和构造函数完全不了解。
我学会了用这种方式创建对象:
@obj = SomeClass.new(:someParameter => 3)
现在,鞋子希望我以这种方式创建对象:
Shoes.app do
@shape = star(points: 5)
motion do |left, top|
@shape.move left, top
end
end
这是另一个例子:
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
为什么会失踪? 为什么鞋子在第一个例子中使用带冒号的语法传递参数?
在第二个例子中,我创建了一个ListCell对象,但我使用了没有new的语法list_cell。 为什么这样做?
这可能是一个非常基本的问题,但我正在尝试学习ruby,我有VB.Net/Java背景,有些事情对我来说很奇怪而且不常见。语法让我感到困惑。
答案 0 :(得分:4)
这只是一个DSL。像star
这样的方法会引用.new
。
冒号语法只是Ruby 1.9.3中引入的另一种哈希语法:
{ :a => :b }
{ a: :b }
这两行做同样的事情。
答案 1 :(得分:2)
Shoes.app do
没有创建实例,这是调用a class method。
这允许直接在类上调用方法,而不必实例化它。
class Foo
def self.hello
puts "hello"
end
end
Foo.hello # outputs "hello"
块形式可能会让您感到困惑,但它是an other ruby idiom允许将一大堆逻辑传递给方法:
def yell( message, &block )
block.call( message.upcase )
end
yell( 'hello' ) do |message|
puts message
end
# outputs "HELLO"
最后,有一种特殊形式的块参数通常用于具有良好外观的配置:在其他上下文中评估的块。
当您调用前一个示例中的块时,块内的代码将无法访问调用它的类中的任何私有方法或变量;它只能访问块声明范围内的内容。
您可以使用#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
所以,基本上,你的鞋子正在结合这三个概念:)
这不是实例化一个类(虽然它可能在引擎盖后面这样做)并且你并不特别需要它,只需像你习惯的那样使用初始化。