<snusnu>
mbj: the integration spec i was talking about yesterday, passes now ;)
<snusnu>
mbj: unit specs are horribly broken ...
<mbj_>
mom, double join
<mbj>
better :D
mbj_ has quit [Client Quit]
<mbj>
snusnu: :D
<snusnu>
mbj: i'm very happy with the design so far, internally it can definitely still be refactored, but i like the general approach
<snusnu>
mbj: will push to a branch in a bit, so you can look at the integration spec and tell me what you think
<snusnu>
mbj: basically i introduced the concept of handler executors, which consist of a Decomposer (split) and a Composer (merge) .. they can be implemented with simple lambdas
<mbj>
snusnu: Registration still confuses me sometimes
<snusnu>
mbj: it's used to give a builtin processor a name, plus an executor
<snusnu>
mbj: processors need names because their failure chains might be overwritten
<snusnu>
mbj: you'll get the idea quickly once you use them
<mbj>
snusnu: I know, but having a dsl for defining a dsl is somehow complex :D
<mbj>
I use them already
<mbj>
But still I find them confusing sometimes :D
<snusnu>
mbj: yeah, it's just dsl after all, we might come up with a better one
<snusnu>
mbj: the idea is to make chain construction as easy as possibly
<snusnu>
mbj: *something* has to *instantiate* the processors
<mbj>
snusnu: Jo
<mbj>
I get the point :D
<snusnu>
mbj: because the chain needs instance
<snusnu>
s
<mbj>
I accept we dont have a better idea :D
<snusnu>
hehe ok
<mbj>
solnic: You need a beta release of mutant with bogus change?
<snusnu>
mbj: i've never heard about hystrix before, i'll look into it at some point .. and let you do the hooking up with substation :p
<solnic>
mbj: not really, it works for me with or without the patch :)
<solnic>
up to you
<snusnu>
yo solnic
<solnic>
hey snusnu
<solnic>
lunch time here, so bbiab
<mbj>
solnic, snusnu: According to information here, mutant will soon support rspec-world preloading. This is the most low hanging performance fuit. https://github.com/rspec/rspec-core/issues/997
<snusnu>
mbj: nice
<snusnu>
mbj: btw, just cause i'm happy .. after the last refactoring, substation almost doesn't allow SRP violations in app code anymore :p
<mbj>
Also this is a prerequisite of implementing the new rspec strategy.
<mbj>
the only prerequisite!
solnic has quit [Quit: Leaving...]
mbj has quit [Read error: Connection reset by peer]
solnic has joined #rom-rb
mbj has joined #rom-rb
cored has quit [Ping timeout: 248 seconds]
cored has joined #rom-rb
<snusnu>
mbj: how do you typically handle scenarios where part of the request data comes from a query string, and part of it is sent with request.body ? i.e. GET/POST params?
<snusnu>
mbj: ok, bbiab
mbj has quit [Ping timeout: 276 seconds]
mbj has joined #rom-rb
solnic has quit [Quit: Leaving...]
mongrelion has left #rom-rb [#rom-rb]
solnic has joined #rom-rb
knowtheory has quit [Quit: Computer has gone to sleep]
<snusnu>
mbj, solnic: do we agree with this rubocop warning: Use the lambda method for multi-line lambdas
<snusnu>
?
<snusnu>
it complains about using -> instead of lambda for multiline lambdas
<snusnu>
imo something like this reads nice enough:
<snusnu>
hey dkubb, mind looking at the question i asked just a minute ago?
<dkubb>
snusnu: ok, one sec. I'll check the history
<snusnu>
dbussink: thx
<dkubb>
oh and good morning
<snusnu>
oops, thx dkubb
<snusnu>
dkubb: good morning :)
<dbussink>
snusnu: i was like, for what? ;)
<snusnu>
dbussink: heh, sorry
<snusnu>
dbussink: altho, make it a thx for your work on rbx ;)
<dkubb>
dbussink: did you move to the US or are you still in the Netherlands?
<dbussink>
dkubb: still in nl
<dbussink>
dkubb: working as a contractor
<dkubb>
snusnu: ok, so my opinion is that GET and POST params shouldn't be mixed into a single object like how Rails does it
<dkubb>
snusnu: typically they serve much different purposes in an application
<snusnu>
dkubb: oh ok, and yeah, i agree with that ;) … i meant my question regarding that rubocop warning tho ;)
<snusnu>
dkubb: it says: Use the lambda method for multi-line lambdas
<dkubb>
snusnu: oh hehe.. one sec. about the -> stabby proc for multiline lambdas?
<snusnu>
dkubb: yup
<dkubb>
snusnu: does -> have the same semantics as lambda() wrt enforcing the arity? or is it more like proc()
* dkubb
is checking this
<snusnu>
dkubb: tbh, i have no idea but assumed that -> was identical to lambda
<snusnu>
dkubb: also, imo i recall seeing arity errors just like with lambdas
<dkubb>
snusnu: aha, it seems like it is the same thing. I have no problem using it instead of lambda. I still have to get used to the syntax, but I do think its neat
<snusnu>
dkubb: yeah, it took me a while too, but i must say i like it
<snusnu>
dkubb: so, i'm gonna disable that warning for substation at least .. we'll see when/if it comes up for rom
<dkubb>
snusnu: so in rubocop it warns against -> for multiline procs?
<snusnu>
dkubb: yup, it advises to use lambda { |x,y| … } instead
<snusnu>
dkubb: and i must say, i see no reason for that
<dkubb>
snusnu: "looks extremely awkward" translates to "I'm not used to this" .. granted some of *our* conventions could also be seen the same way, but I'd like to think we have slightly stronger reasons
<snusnu>
dkubb: right, imo they absolutely don't look "extremely awkward"
machuga is now known as machuga|away
<dkubb>
snusnu: I think moving the argument outside of {} is nice. it looks more like a method call
mbj_ has joined #rom-rb
<snusnu>
dkubb: right, that's my reasoning too
<snusnu>
dkubb: also, as the code gets more and more functional, it seems to fit even more
<snusnu>
dkubb: and by functional i don't mean it works, but uknowwhat
<snusnu>
:)
<dkubb>
snusnu: yeah. I don't actually use inline procs too much either, so any decision we make it going to only affect a small part of the code
<dkubb>
:)
<snusnu>
dkubb: yeah, i have this usecase in substation currently, where a simple lambda is enough to provide a basic implementation of the concept .. more involved usecases might implement a dedicated class that responds to #call, but right now the lambda is enough
<snusnu>
dkubb: i can link you to those parts in a bit, if you're interested
<dkubb>
snusnu: I actually use that a lot in axiom too. many of the objects represent a callable object
<snusnu>
dkubb: the idea here is that before Deserializer#call gets invoked, the EXECUTOR will first decompose, then compose the incoming data
<dkubb>
snusnu: what's request.input mean?
<snusnu>
dkubb: it's what the user passed in as "input data" … as it goes through the chain, it gets more and more refined to finally represent valid input data for the business use case
<dkubb>
ahh I see
<snusnu>
dkubb: so the step i linked in that pastie, does the deserializing .. it gets passed the complete Request instance (which responds to #name, #env, #input)
<snusnu>
dkubb: but it must "decompose" that, to send something specific to the handler
<snusnu>
dkubb: but the handler might just refine "one slot" of the input .. so it must compose it back to the complete input data object after it's done
<snusnu>
dkubb: SRP to the extreme ;)
<dkubb>
snusnu: I find it hard to balance SRP and LoD
<snusnu>
dkubb: yeah, altho tbh, with current substation handlers, no particularly bad LoD violation caught my eyes so far
<snusnu>
dkubb: i guess that'll change over time tho ;) we'll see
<snusnu>
dkubb: also, it somewhat depends of the "goal" of the code .. like with this "decomposition" .. i accept that i need to "walk some path into the object" .. because well, that's what it's supposed to do
<snusnu>
dkubb: the input data object itself is free to provide helper methods to reduce LoD violation
<snusnu>
s
<snusnu>
dkubb: the Substation::Request object not, it has it's own, tiny api
<snusnu>
dkubb: so inside that DECOMPOSER inside the pastie .. i will add LoD aware methods to the object at request.input .. that would allow me to do: request.input.whatever
<snusnu>
dkubb: i'll most likely not add anything to request tho, in order to do request.whatever .. that'd just pollute the Request api
<snusnu>
mbj_: still needs quite some refactoring before it can be merged into master, but i like it so far
mbj_ is now known as mbj
<snusnu>
mbj: the integration spec passes, but as i said, unit specs are broken to the max
<snusnu>
mbj: but yeah, it does split/merge now
<snusnu>
mbj: for more complex split/merge (decompose/compose) i guess one would have to implement dedicated classes instead of the current lambdas .. i don't see anything that would prevent us from splitting/merging "n paths" (instead of the current 2)
solnic has quit [Quit: Leaving...]
<snusnu>
mbj: even in separate threads … that logic would have to be defined inside a Decomposer/Composer pair used by the handler that needs the parallel (de)compose
therabidbanana has joined #rom-rb
zekefast has quit [Quit: Leaving.]
zekefast has joined #rom-rb
zekefast has quit [Client Quit]
mbj has quit [Remote host closed the connection]
snusnu has quit [Quit: Leaving.]
mbj has joined #rom-rb
machuga|away is now known as machuga
zekefast has joined #rom-rb
cored has quit [Ping timeout: 248 seconds]
cored has joined #rom-rb
cored has quit [Changing host]
cored has joined #rom-rb
mbj_ has joined #rom-rb
mbj has quit [Ping timeout: 268 seconds]
snusnu has joined #rom-rb
<dkubb>
cored: have you pushed any of the axiom types refactor commits you have locally?
zekefast has quit [Quit: Leaving.]
mbj_ has quit [Read error: Connection reset by peer]
mbj has joined #rom-rb
<dkubb>
mbj: good morning
<mbj>
dkubb: hola
<elskwid>
Howdy all
<mbj>
elskwid: hola
<dkubb>
elskwid: hello
mbj has quit [Read error: Connection reset by peer]
mbj has joined #rom-rb
<elskwid>
How are you?
<elskwid>
mbj: How was the conf?
<mbj>
elskwid: eurucamp?
<mbj>
elskwid: Still upcoming. 16. Aug.
<elskwid>
mbj: Oh, well, shows what I know!!
<elskwid>
Let's just pretend I didn't ask that.
<elskwid>
How about this:
<elskwid>
mbj: How's the family?
<mbj>
elskwid: We are fine.
<mbj>
elskwid: Just came back from a 10h train ride, paused by a 2h meeting
<mbj>
My brain is not able to do social communication anymore.
<mbj>
Lets talk about code!
<mbj>
Preparing mutant to hook deeper into rspec to preload the world.
<mbj>
this will allow much faster mutation kills.
<mbj>
But TBH the internals of rspec are not rom-style :(
<elskwid>
mbj: Have you all considered making the move to minitest?
<elskwid>
(sorry if that's already come up, just curious)
<mbj>
elskwid: I want to support all test frameworks.
<mbj>
It will not make sense mutant is tied to a specific one.
<elskwid>
great to hear
<mbj>
That rspec core example filtering is far more complex than axiom :D
knowtheo1y has joined #rom-rb
knowtheo2y has joined #rom-rb
knowtheo1y has quit [Read error: Connection reset by peer]
knowtheory has quit [Ping timeout: 264 seconds]
<dkubb>
I've considered minitest, but I don't know if the effort to switch would be worth it at this point
<dkubb>
what I would actually prefer is having something really minimal that matches the way we write specs
<dkubb>
once we start talking about switching to make it worthwhile it needs to be a big improvement
<mbj>
dkubb: +1
<dkubb>
I think we can probably get a big improvement by doing some things differently than the main test frameworks
<dkubb>
for example, given that we use immutable objects quite often, we can make it so a single object is initilaized and then reused between examples
<dkubb>
the examples can also be threaded
<mbj>
dkubb: I'll create such a framework :D
<dkubb>
there'd need to be a way to say "serialize", which would wrap each example in a mutex.. for cases where stuff is not thread safe, but I would generally want to assume the code is thread safe by default
<mbj>
Probably I'd end up using axiom-predicates to filter
<dkubb>
yeah, we can stuff to handle query methods differently from command methods
<mbj>
rspec-core could need a rom-style refactoring
<mbj>
With immutable objects!
<dkubb>
hehe
<dkubb>
rspec-core is probably 10x larger than we need
<dkubb>
if we're talking about just the functionality we use
<mbj>
yeah
<mbj>
It would be "so" easy to implement that stuff we use.
<mbj>
I just see minimal classes instantiated via a small dsl layer.
<mbj>
rspec-core mixes dsl and OO api
<dkubb>
I think mutant is probably higher priority for me.. rounding out those mutations
<dkubb>
I actually really like rspec 3's new syntax
<dkubb>
it seems much simpler to implement
<dkubb>
we could even reuse rspec-expectations and rspec-mocks, and just have a tighter core
<mbj>
The problem is: The core is so mutable. It is very uneasy for me to follow control flow.
<mbj>
It gets mutated all over the place.
<mbj>
So just query the core for a set of examples, and run these seems to be nearly implossible
<mbj>
All "control" structures seem to be mutated and used on the fly.
<mbj>
Also rspec has far to much configuration :D
<dkubb>
heh, too bad you can't deep clone, then deep freeze it and then just reuse it
<mbj>
dkubb: I have the killfork, so I can delay some "mutations" and do them inside the fork.
<mbj>
this will not leak
<mbj>
But it is overcomplex.
<mbj>
dkubb: One thing I realize with rom-style code more and more. It is very easy to come back later.
knowtheory has joined #rom-rb
knowtheory has quit [Read error: Connection reset by peer]
knowtheory has joined #rom-rb
<dkubb>
mbj: yeah, it is much nicer to work with
<dkubb>
mbj: the thing we need to prove is that it results in better larger systems. I think we've already proven it results in great small systems (like gems)
<mbj>
dkubb: It is hard to prove this for large systems, because we do small gems :D
knowtheo2y has quit [Ping timeout: 248 seconds]
<mbj>
And I cannot opensource my clients work :D
<dkubb>
I have one project I worked on over the last year, and I did incorporate as many ROM style coding standards as I could, and I think it's pretty good
<mbj>
dkubb: nice
<dkubb>
I didn't do mutation testing because I started it before mutant was ready
<dkubb>
if I did it today I probably would've
<mbj>
dkubb: Yeah, I see a big difference in "pre mutant" software I shipped.
<dkubb>
my newest rails project uses mutant
<dkubb>
and it's awesome. the only bugs I've seen with this project have been in the original specification
<dkubb>
like what the client specified
<dkubb>
the actual software does precisely what it was designed to do
<dkubb>
so far anyway
<mbj>
dkubb: nice, I could need some testamonial for my talk :D
<dkubb>
mutation testing is my secret weapon
<mbj>
heh, yeah
<mbj>
I had a Q&A workshop this day, and it seems I could convince the companies Q&A officer it leads to high quality
<mbj>
Kist ran mutant on a covered pice of code
<mbj>
Nuked context, and reran.
<mbj>
He realized how helpful this tool is to uncover missing tests
<dkubb>
oh nice
<dkubb>
I think a Q&A person would totally understand it
<dkubb>
mbj: how many mutations did it find?
<mbj>
dkubb: Removing a single context? 5
zekefast has joined #rom-rb
<dkubb>
mbj: oh I see what you meant
<dkubb>
mbj: I thought maybe you ran it on their code that was showing 100% simplecov coverage, and then discovered missing cases
<mbj>
dkubb: nope, I presented my own work
<mbj>
dkubb: This is a greenfield project.
<mbj>
Okay it is a reimplementation but without code share
<mbj>
original is in php, no comments :d
<cored>
hello
<mbj>
cored: hola
<cored>
;-)
<cored>
dkubb: are you around?
machuga is now known as machuga|away
<cored>
mbj: well, I'm having some sort of a same discussion
<cored>
mbj: a friend saying that Ruby sucks, because he can't use a debugger like in VS .NET
<cored>
mbj: saying this because of your comment on PHP
<cored>
hehe
<mbj>
cored: TBH I never used a debugger in ruby
<mbj>
cored: Only use a debugger for embedded devices and C code.
<cored>
he, it could be fun if you tell that to hi
<mbj>
For some reason "Kernel#p" is the most I need.
<cored>
s/hi/him
<cored>
in fact, he is checking out Scala because .NET is from MS but he was telling me that he was considering going back to .NET
<cored>
he said that he have like 3 weeks trying to build an application with Rails and that he hasn't make any progress
<cored>
quantificable progress at least, he said that Ruby promote the fact to not separate classes in different files because there's no tooling for such thing
<mbj>
cored: I cannot really reply with some wise words here :D
<mbj>
Dunno your friend nor the rails project, nor the domain :D
<cored>
hehehe
<cored>
he wants to do a similar app to Buxfer
<cored>
a personal finance application
<dkubb>
binding.pry is actually pretty neat for debugging
<cored>
dkubb: I told him
<cored>
but he said that in VS he has something called inspector or something like that and that he founds on Ruby was pry
<mbj>
dkubb: I have to try it.
<dkubb>
I don't use a debugger either, but somestimes it's nice to stop the world and poke around
<cored>
also he said that Ruby sucks entirely
<dkubb>
I usually use puts or p too
<dkubb>
hehe
<cored>
dkubb: yes, that's how I try to figure out things within axiom
<mbj>
dkubb, cored: I know ruby sucks and I agree with all people saying ruby sucks. But for some reason I can write code I like in this language, and IMHO other languages suck even more :D
<cored>
he is kinda frustrated, he was talking about the impediment of building a fully DDD arquitecture using Rails, the impediment of dividing your application in different gem's if you are using Rails
<cored>
mbj: hahahaha
<mbj>
dkubb: The more I interface with rspec-core internals the more mental discipline I need to not start a freaking clone now.
<cored>
Attribute.infer_type will return an Axiom::Types object
<cored>
but there's no method named type on any of the objects from Axiom::Types
<dkubb>
oh yeah, I think that's one of the holes we need to think about filling
<cored>
I see
<cored>
there's no such thing as an abstract attribute type inside axiom-types as far as I know
<dkubb>
we may need to change that code completely since the Axiom::Types know nothing about Axiom::Attribute, nor should they
<cored>
exactly
<dkubb>
so it should first infer the type from the object, then it should take the type *and* the attribute and coerce it into an Axiom::Attribute that matches it
knowtheory has joined #rom-rb
<cored>
I thought that the hold purporse of the refactoring was to remove Axiom::Attribute ?
<dkubb>
removing Axiom::Attribute subclasses you mean
<dkubb>
Axiom::Attribute still needs to exist in some form, since it holds a name *and* a type
<dkubb>
the big question is how we're going to add type specific functions to attributes
<dkubb>
I was trying to do the refactoring in two parts, one to push out type specific constraints into axiom-types (which we're doing now) and a second pass to remove Axiom::Attribute subclasses and figure out a different way to add type specific functions; whether that's through a proxy or some other object I don't know yet
<dkubb>
how we do it isn't as important to me as the interface in the end. I would want to be able to make an attribute using: Axiom::Attribute.new(name, type)
<dkubb>
and if type is Axiom::Types::String, then I want to be able to do: Axiom::Attribute.new(name, type).length.eq(5)
<dkubb>
but if it is an integer type, say, I do not want #length to be available or callable
postmodern has joined #rom-rb
<dkubb>
this will allow things like: relation.restrict { |r| r[:name].length.eq(5) }
<dkubb>
where r[:name] returns an Axiom::Attribute with a name of ":name", and a type of Axiom::Types::String
<dkubb>
cored: does that make more sense?
<cored>
just a sec, thinking about it :-)
<dkubb>
I think if we try to do two steps in one jump we'll fail.. I'd rather do it in two steps and have a working system in between, even if it means some temporarily ugly code in a few places
<cored>
agree
<dkubb>
for the most part the code we're had to write has been fine. this will probably be one of the areas with something a bit funkier.. we could push it off into a singleton method with a note to review it later
<cored>
the only downside is that we already did the first part, I guess
<cored>
I think this is a problem related to the second part
<dkubb>
I wouldn't say the first part is completely done
<dkubb>
we still have Axiom::Attribute subclasses
<dkubb>
it's that they exist almost soley for hanging type specific functions off.. all the type and constraint related logic is now in the type
<cored>
wAxiom::Attribute::Integer
<cored>
you mean?
<dkubb>
yeah
<cored>
I see
<dkubb>
after step 2 those would theoretically go away or be really minimized
<cored>
so still that's needs to be done before going to the evaluator, I guess
<dkubb>
this is thinking ahead, but in the future we could have (in Axiom::Attribute) def method_missing(*args); methods_for(type).public_send(self, *args); end ... or something like that
<dkubb>
the idea being that we don't have Axiom::Attribute subclasses to hang the methods from, but something else rather
<dkubb>
I guess it depends on what we decide. if most of the logic is out of the Axiom::Attribute subclasses, and this alternate lookup approach is too messy, then we may just keep them as dumb containers
<cored>
don't know if at this point is a good idea to have method_missing
<cored>
but removing the subclasses probably that will be the fastest way to solve the current problem
<dkubb>
we can't remove the subclasses yet
<dkubb>
we won't have any place to hang the type specific functions
<dkubb>
type specific functions are extremely important to how axiom works.. every attribute subclass has different functions you can call on it
<dkubb>
it's used in the context evaluator mostly, but it can be used outside it
<cored>
I was thinking in doing something kinda stupid to remove the sub types but in that case we will haev a lot of loose methods on a lot of modules
<dkubb>
it's tricky because we don't want to do runtime extension or anything like that
<dkubb>
we really can't because the objects are immutable, but even if they weren't I wouldn't want to do that because of the runtime perf impact
<cored>
I see
<cored>
sounds like a very complex problem :-)
<dkubb>
I dunno, I'm trying not to worry about it
<dkubb>
I don't want to approach it until we have a working base
<cored>
by working base I guess you mean all specs passing
<cored>
right ?
<dkubb>
what we're doing right now is the smallest unit of work I can think of to make this change
<dkubb>
yeah
<cored>
well, I think I have to finish the first step then
<cored>
because if the evalualtor probably is because of that
<cored>
the thing is that there are different subtypes which Attribute.infer_type will return so each one will have it's own implementation of #type
<cored>
correct?
<dkubb>
lemme check what infer_type does now
<dkubb>
cored: have you got any local commits to that branch that you need to push?
<dkubb>
cored: yup. I was hoping you had an approach that you understood.
<cored>
well the problem that I have currently is the different implementation for each type
<cored>
in fact what any axiom-type object doesn't have is the #coerce method as far I as I can see
<cored>
anyway, will take a break and will try to keep checking the code
<dkubb>
the rough approach I would use will be to iterate over Axiom::Attribute subclasses to find the one with the inferred type, then use that to construct the attribute to use within the functions Hash
<cored>
the attribute from within axiom
<cored>
I see
<cored>
I see your idea now, more clearly
<cored>
in that case the need of coerce won't be needed, right ?
<dkubb>
I don't think it'll be needed.. we're basically taking on control of coercion ourselves
<dkubb>
I would fully expect this code to be temporary
<cored>
ok
<cored>
let me try that
<dkubb>
and if it's not then we can move it somewhere else after, but passing specs is the #1 priority
<cored>
got it
<cored>
does the descendants attribute include the axiom type
<cored>
or is the other way around?
<cored>
I guess there is a namespace mismatch, something like Axiom::Types::Integer != Axiom::Attribute::Integer
<dkubb>
yeah, both of them have descendants methods
<dkubb>
but they aren't the same kind of object obviously
<cored>
well, I was thinking on stripping out the entire namespace from the class name and comparing Strings
<dkubb>
there should be a type method on each Axiom::Attribute subclass that relates them
<cored>
ok
<cored>
was doing a pretty ugly thing
<snusnu>
dkubb: hey, can i ask you a follow up question wrt GET/POST parameters passed to some web action?
<snusnu>
dkubb: say you get passed an object as action input, something like Input#{actor, params} where #params would contain GET+POST params (i don't want that) … how would you design the api of the object returned by #params so that GET/POST params are separate .. or would you rather do something like Input#{actor, get_params, post_params) .. (ugly names, but you get the idea?)
<snusnu>
dkubb: i'm mostly talking about naming here i guess .. maybe it's just fine to wrap both types of params into a Params instance made accessible via Input#params
<snusnu>
dkubb: but yeah, i'm very open to any idea ;)
<snusnu>
dkubb: fwiw, Input#actor basically is a simple wrapper around session data, which has an instantiated domain specific actor object instantiated already (think rails current_user, only with privileges and such attached already)
<snusnu>
dkubb: it's the Input#data object that i'm actually talking about .. i want that to make GET and POST params accessible, but separate from each other