Skip to content

Commit

Permalink
Showing 2 changed files with 148 additions and 30 deletions.
33 changes: 33 additions & 0 deletions spec/std/object_spec.cr
Original file line number Diff line number Diff line change
@@ -27,6 +27,14 @@ module ObjectSpec
getter? getter9 : Bool = true
getter? getter10 = true

getter(getter11) { 11 }

@@getter12_value = 12
getter getter12 : Int32 { @@getter12_value }

def self.getter12_value=(@@getter12_value)
end

setter setter1
setter setter2 : Int32
setter setter3 : Int32 = 3
@@ -47,6 +55,9 @@ module ObjectSpec
property? property9 : Bool = true
property? property10 = true

property(property11) { 11 }
property property12 : Int32 { 10 + 2 }

def initialize
@getter1 = 1
@getter2 = 2
@@ -137,6 +148,17 @@ describe Object do
typeof(obj.@getter4).should eq(Int32)
typeof(obj.getter4).should eq(Int32)
end

it "defines lazy getter with block" do
obj = ObjectSpec::TestObject.new
obj.getter11.should eq(11)
obj.getter12.should eq(12)
ObjectSpec::TestObject.getter12_value = 24
obj.getter12.should eq(12)

obj2 = ObjectSpec::TestObject.new
obj2.getter12.should eq(24)
end
end

describe "getter!" do
@@ -251,6 +273,17 @@ describe Object do
obj.property4 = 5
obj.property4.should eq(5)
end

it "defines lazy property with block" do
obj = ObjectSpec::TestObject.new
obj.property11.should eq(11)
obj.property11 = 12
obj.property11.should eq(12)

obj.property12.should eq(12)
obj.property12 = 13
obj.property12.should eq(13)
end
end

describe "property!" do
145 changes: 115 additions & 30 deletions src/object.cr
Original file line number Diff line number Diff line change
@@ -251,25 +251,65 @@ class Object
# end
# end
# ```
macro getter(*names)
{% for name in names %}
{% if name.is_a?(TypeDeclaration) %}
@{{name}}
#
# If a block is given to the macro, a getter is generated
# with an instance variable that is lazily initialized with
# the block's contents:
#
# ```
# class Person
# getter(birth_date) { Time.now }
# end
# ```
#
# Is the same as writing:
#
# ```
# class Person
# def birth_date
# @birth_date ||= Time.now
# end
# end
# ```
macro getter(*names, &block)
{% if block %}
{% if names.size != 1 %}
{{ raise "only one argument can be passed to `getter` with a block" }}
{% end %}

def {{name.var.id}} : {{name.type}}
@{{name.var.id}}
end
{% elsif name.is_a?(Assign) %}
@{{name}}
{% name = names[0] %}

def {{name.target.id}}
@{{name.target.id}}
{% if name.is_a?(TypeDeclaration) %}
@{{name.var.id}} : {{name.type}}?

def {{name.var.id}}
@{{name.var.id}} ||= {{yield}}
end
{% else %}
def {{name.id}}
@{{name.id}}
@{{name.id}} ||= {{yield}}
end
{% end %}
{% else %}
{% for name in names %}
{% if name.is_a?(TypeDeclaration) %}
@{{name}}

def {{name.var.id}} : {{name.type}}
@{{name.var.id}}
end
{% elsif name.is_a?(Assign) %}
@{{name}}

def {{name.target.id}}
@{{name.target.id}}
end
{% else %}
def {{name.id}}
@{{name.id}}
end
{% end %}
{% end %}
{% end %}
end

@@ -664,33 +704,78 @@ class Object
# end
# end
# ```
macro property(*names)
{% for name in names %}
{% if name.is_a?(TypeDeclaration) %}
@{{name}}
#
# If a block is given to the macro, a property is generated
# with an instance variable that is lazily initialized with
# the block's contents:
#
# ```
# class Person
# property(birth_date) { Time.now }
# end
# ```
#
# Is the same as writing:
#
# ```
# class Person
# def birth_date
# @birth_date ||= Time.now
# end
#
# def birth_date=(@birth_date)
# end
# end
# ```
macro property(*names, &block)
{% if block %}
{% if names.size != 1 %}
{{ raise "only one argument can be passed to `property` with a block" }}
{% end %}

def {{name.var.id}} : {{name.type}}
@{{name.var.id}}
end
{% name = names[0] %}

def {{name.var.id}}=(@{{name.var.id}} : {{name.type}})
end
{% elsif name.is_a?(Assign) %}
@{{name}}
setter {{name}}

def {{name.target.id}}
@{{name.target.id}}
end
{% if name.is_a?(TypeDeclaration) %}
@{{name.var.id}} : {{name.type}}?

def {{name.target.id}}=(@{{name.target.id}})
def {{name.var.id}}
@{{name.var.id}} ||= {{yield}}
end
{% else %}
def {{name.id}}
@{{name.id}}
@{{name.id}} ||= {{yield}}
end
{% end %}
{% else %}
{% for name in names %}
{% if name.is_a?(TypeDeclaration) %}
@{{name}}

def {{name.id}}=(@{{name.id}})
end
def {{name.var.id}} : {{name.type}}
@{{name.var.id}}
end

def {{name.var.id}}=(@{{name.var.id}} : {{name.type}})
end
{% elsif name.is_a?(Assign) %}
@{{name}}

def {{name.target.id}}
@{{name.target.id}}
end

def {{name.target.id}}=(@{{name.target.id}})
end
{% else %}
def {{name.id}}
@{{name.id}}
end

def {{name.id}}=(@{{name.id}})
end
{% end %}
{% end %}
{% end %}
end

0 comments on commit 765072c

Please sign in to comment.