3 kyu

The builder of things

151 of 1,029jhoffner

Description:

For this kata you will be using some meta-programming magic to create a new Thing object. This object will allow you to define things in a descriptive sentence like format.

This challenge attempts to build on itself in an increasingly complex manner.

Examples of what can be done with "Thing":

jane = Thing.new('Jane')
jane.name # => 'Jane'

# can define boolean methods on an instance
jane.is_a.person
jane.is_a.woman
jane.is_not_a.man

jane.person? # => true
jane.man? # => false

# can define properties on a per instance level
jane.is_the.parent_of.joe
jane.parent_of # => 'joe'

# can define number of child things
# when more than 1, an array is created
jane.has(2).legs
jane.legs.size # => 2
jane.legs.first.is_a?(Thing) # => true

# can define single items
jane.has(1).head

jane.head.is_a?(Thing) # => true

# can define number of things in a chainable and natural format
jane.has(2).arms.each { having(1).hand.having(5).fingers }

jane.arms.first.hand.fingers.size # => 5

# can define properties on nested items
jane.has(1).head.having(2).eyes.each { being_the.color.blue.and_the.shape.round }

# can define methods
jane.can.speak('spoke') do |phrase|
  "#{name} says: #{phrase}"
end

jane.speak("hello") # => "Jane says: hello"

# if past tense was provided then method calls are tracked
jane.spoke # => ["Jane says: hello"]
const jane = new Thing('Jane')
jane.name // => 'Jane'

// can define boolean methods on an instance
jane.is_a.person
jane.is_a.woman
jane.is_not_a.man

jane.is_a_person // => true
jane.is_a_man // => false

// can define properties on a per instance level
jane.is_the.parent_of.joe
jane.parent_of // => 'joe'

// can define number of child things
// when more than 1, an array is created
jane.has(2).legs
jane.legs.length // => 2
jane.legs[0] instanceof Thing // => true

// can define single items
jane.has(1).head

jane.head instanceof Thing // => true

// can define number of things in a chainable and natural format
jane.has(2).arms.each(arm => having(1).hand.having(5).fingers )

jane.arms[0].hand.fingers.length // => 5

// can define properties on nested items
jane.has(1).head.having(2).eyes.each( eye => being_the.color.blue.having(1).pupil.being_the.color.black )

// can define methods
jane.can.speak('spoke', phrase =>
  `${name} says: ${phrase}`)

jane.speak("hello") // => "Jane says: hello"

// if past tense was provided then method calls are tracked
jane.spoke // => ["Jane says: hello"]
jane = new Thing 'Jane'
jane.name # => 'Jane'

# can define boolean methods on an instance
jane.is_a.person
jane.is_a.woman
jane.is_not_a.man

jane.is_a_person # => true
jane.is_a_man # => false

# can define properties on a per instance level
jane.is_the.parent_of.joe
jane.parent_of # => 'joe'

# can define number of child things
# when more than 1, an array is created
jane.has(2).legs
jane.legs.length # => 2
jane.legs[0] instanceof Thing # => true

# can define single items
jane.has(1).head

jane.head instanceof Thing # => true

# can define number of things in a chainable and natural format
jane.has(2).arms.each (arm)-> having(1).hand.having(5).fingers

jane.arms[0].hand.fingers.length # => 5

# can define properties on nested items
jane.has(1).head.having(2).eyes.each (eye) ->
  being_the.color.blue.with(1).pupil.being_the.color.black

# can define methods
jane.can.speak 'spoke', (phrase)-> "#{name} says: #{phrase}"

jane.speak 'hello' # => 'Jane says: hello'

# if past tense was provided then method calls are tracked
jane.spoke # => ['Jane says: hello']
jane = Thing('Jane')
jane.name # => 'Jane'

# can define boolean methods on an instance
jane.is_a.person
jane.is_a.woman.is_not_a.man

jane.is_a_person # => True
jane.is_a_man # => False

# can define properties on a per instance level
jane.is_the.parent_of.joe
jane.parent_of # => 'joe'

# can define number of child things
# when more than 1, the resulting Thing must be a sequence and must be an iterable
legs = jane.has(2).legs
len(legs) # => 2
isinstance(legs, Thing) # => True
isinstance(jane.legs[0], Thing) # => True

# can define single items
jane.has(1).head.is_the.on_top_of.body
isinstance(jane.head, Thing) # => True
jane.head.on_top_of # => "body"

# can define number of things in a chainable and natural format
jane.has(2).hands.each(lambda h:h.having(5).fingers)
len(jane.arms[0].hand.fingers) # => 5

# can define properties on nested items
jane.has(2).eyes.each(lambda thing: thing.being_the.color.green.having(1).pupil.being_the.color.black)

# can define methods: thing.can.verb(method, archive=None)
def method(self_:Thing, phrase:str): 
    return f"{self_.name} says: {phrase}"
jane.can.speak(method, "spoke")

jane.speak("hello") # => "Jane says: hello"
jane.speak("bye") # => "Jane says: bye"

# if archive was provided then method results are tracked
jane.spoke # => ["Jane says: hello", "Jane says: bye"]

Note: Most of the test cases have already been provided for you so that you can see how the Thing object is supposed to work.

Metaprogramming
Domain Specific Languages
Algorithms
Language Features

Similar Kata:

More By Author:

Check out these other kata created by jhoffner

Stats:

CreatedJun 5, 2015
PublishedJun 5, 2015
Warriors Trained11363
Total Skips4020
Total Code Submissions13907
Total Times Completed1029
Ruby Completions151
JavaScript Completions594
Python Completions296
CoffeeScript Completions4
Total Stars740
% of votes with a positive feedback rating90% of 265
Total "Very Satisfied" Votes220
Total "Somewhat Satisfied" Votes38
Total "Not Satisfied" Votes7
Total Rank Assessments6
Average Assessed Rank
1 kyu
Highest Assessed Rank
1 kyu
Lowest Assessed Rank
3 kyu
Ad
Contributors
  • jhoffner Avatar
  • Abbe Avatar
  • Blind4Basics Avatar
  • SFaghihi Avatar
  • Voile Avatar
  • metalim Avatar
  • Glyxerine Avatar
  • trashy_incel Avatar
  • jpssj Avatar
Ad