edisonywh / behaves Goto Github PK
View Code? Open in Web Editor NEWDefine behaviors and contracts between your code.
License: MIT License
Define behaviors and contracts between your code.
License: MIT License
Currently behaves
uses at_exit
to run checks for behaves_like
. The problem with this is that this screws with rspecs
's raise_error
.
I've opened up an issue over at rspec/rspec-expectations#1117
I'm trying to look for an alternative if there's one, feel free to make a PR if you know of any.
The reason for using at_exit
is as follow:
The point of at_exit
is so that you can put your behaves_like
at the top of the file.
Because code is evaluated from top to bottom, there's no way for behaves_like
to know what method the class has implemented, unless you put it all the way down at the bottom, after the declaration of all methods, which is ugly and unconventional.
As of now the current behavior is if class B doesn't implement the #run
function, it will fail.
class A
extends Behave
implements :run
end
class B
extends Behave
behaves_like A
end
What if we have something like this, class B behaves like A
but lets say they have a common function with the same implementation logic, in that case class B
don't necessarily have to implement the method #run
again, so when an instance of class B
invokes #run
we will now call the function defined in class A
.
class A
extends Behave
implements :run
def run
"run somewhere"
end
end
class B
extends Behave
behaves_like A
end
b = B.new
b.run() -> invokes the function defined in A. # run somewhere
The example class Animal
seems useless (for creating objects)
Also would be good to have example for "multi-inheritance"
module Hunter
extend Behaves
implements(:hunt)
end
module Prey
extend Behaves
implements(:run, :hide)
end
class Shark
extend Behaves
behaves_like Hunter
behaves_like Prey
# Something something
end
As pointed out by @PikachuEXE over at #12, errors won't actually get raised until exit
is called. This is because of the use of at_exit
, which only gets run... at exit.
Pikachu has proposed a new syntax, which uses block to mitigate this issue over at #12.
I'm not sure what's the best way to go about this here so opening this up for discussion, however Pikachu's proposal, despite changes the usage, has the cleanest strategy so far, so I'm leaning towards that.
After cloning behaves
, in the same folder you can do bin/console
which brings up a console to play with.
Paste in this snippet of code:
class Animal
extend Behaves
implements :method_one, :method_two
end
class Dog
extend Behaves
behaves_like Animal
end
exit
.Anyone care to chime in? :)
Currently, the tests are pretty simplistic in that it always çreate the Behavior Object
as a class. Logically (untested) it should more or less work the same for Module
, but it's good to add specs for some sanity check and to verify that it actually works.
When specs are added and it is verified to work, we could also add this into the README detailing that both Module
and Class
would work.
See #13
class Animal
extend Behaves
implements :method_one
end
class Dog
extend Behaves
behaves_like Animal
def method_1
"hello"
end
end
When we do this:
dog = Dog.new
dog.behaves_like # returns Animal
I may have a collection of objects, and i will like to do some operations on them. Hence i can decide if these object behaves_like a certain type, i want perform an operation which is related to this class, since it will definitely define the method its required to implement and the injected behavior.
irb(main):001:0> require 'behaves'
=> true
irb(main):002:0> class Animal
irb(main):003:1> extend Behaves
irb(main):004:1>
irb(main):005:1> implements :speak, :eat
irb(main):006:1> end
NameError: uninitialized constant Behaves::Set
from /Users/jimmy/.rbenv/versions/2.3.3/lib/ruby/gems/2.3.0/gems/behaves-0.1.0/lib/behaves.rb:5:in `implements'
from (irb):6:in `<class:Animal>'
from (irb):6
from /Users/jimmy/.rbenv/versions/2.3.3/bin/irb:11:in `<main>'
I ended up adding this as an initializer
Object.send :extend, Behaves
to avoid typing extend Behave
all the time.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.