solnic changed the topic of #rom-rb to: Ruby Object Mapper | Mailing List: https://groups.google.com/forum/?fromgroups#!forum/rom-rb | Logs: http://irclog.whitequark.org/rom-rb
lfox has joined #rom-rb
bf4 has quit [Ping timeout: 252 seconds]
lgierth has quit [Quit: Ex-Chat]
cored has quit [Ping timeout: 246 seconds]
cored has joined #rom-rb
jgaskins has quit [Quit: This computer has gone to sleep]
cored has quit [Ping timeout: 252 seconds]
bf4 has joined #rom-rb
bf4 has quit [Ping timeout: 272 seconds]
cored has joined #rom-rb
snusnu has joined #rom-rb
cored has quit [Ping timeout: 272 seconds]
cored has joined #rom-rb
cored has quit [Ping timeout: 272 seconds]
bf4 has joined #rom-rb
bf4 has quit [Read error: Operation timed out]
lfox has quit [Quit: ZZZzzz…]
snusnu has quit [Quit: Leaving.]
snusnu has joined #rom-rb
postmodern has quit [Quit: Leaving]
bf4 has joined #rom-rb
bf4 has quit [Ping timeout: 245 seconds]
adkron has quit [Ping timeout: 264 seconds]
adkron has joined #rom-rb
adkron has quit [Ping timeout: 246 seconds]
bf4 has joined #rom-rb
bf4 has quit [Ping timeout: 240 seconds]
snusnu has quit [Ping timeout: 252 seconds]
martxel has quit [Ping timeout: 246 seconds]
martxel_ has joined #rom-rb
martxel_ is now known as Guest97410
bf4 has joined #rom-rb
Guest97410 has quit [Ping timeout: 264 seconds]
bf4 has quit [Ping timeout: 246 seconds]
adkron has joined #rom-rb
adkron has quit [Ping timeout: 246 seconds]
lfox has joined #rom-rb
adkron has joined #rom-rb
adkron has quit [Ping timeout: 272 seconds]
mbj has joined #rom-rb
bf4 has joined #rom-rb
Guest97410 has joined #rom-rb
bf4 has quit [Ping timeout: 272 seconds]
lfox has quit [Quit: ZZZzzz…]
mbj has quit [Ping timeout: 264 seconds]
bf4 has joined #rom-rb
bf4 has quit [Ping timeout: 252 seconds]
mbj has joined #rom-rb
bf4 has joined #rom-rb
bf4 has quit [Ping timeout: 272 seconds]
mbj has quit [Read error: Connection reset by peer]
postmodern has joined #rom-rb
bf4 has joined #rom-rb
bf4 has quit [Ping timeout: 248 seconds]
mbj has joined #rom-rb
bf4 has joined #rom-rb
bf4 has quit [Ping timeout: 252 seconds]
cored has joined #rom-rb
postmodern has quit [Quit: Leaving]
cored has quit [Ping timeout: 246 seconds]
cored has joined #rom-rb
bf4 has joined #rom-rb
kapowaz has quit [Remote host closed the connection]
bf4 has quit [Ping timeout: 246 seconds]
avdi has quit [Remote host closed the connection]
cory_ has quit [Remote host closed the connection]
cbuxton_ has quit [Remote host closed the connection]
kapowaz has joined #rom-rb
avdi has joined #rom-rb
breakingthings has joined #rom-rb
cory_ has joined #rom-rb
<mbj> dkubb: hi
cbuxton_ has joined #rom-rb
adkron has joined #rom-rb
cored has quit [Ping timeout: 264 seconds]
lfox has joined #rom-rb
jgaskins has joined #rom-rb
cored has joined #rom-rb
cored has quit [Changing host]
cored has joined #rom-rb
cored has quit [Ping timeout: 248 seconds]
cored has joined #rom-rb
cored has joined #rom-rb
adkron has quit [Ping timeout: 245 seconds]
snusnu has joined #rom-rb
adkron has joined #rom-rb
CraigBuchek has joined #rom-rb
snusnu has quit [Quit: Leaving.]
cored has quit [Ping timeout: 272 seconds]
cored has joined #rom-rb
bf4 has joined #rom-rb
snusnu has joined #rom-rb
adkron has quit [Ping timeout: 265 seconds]
<snusnu> yo mbj
<snusnu> i'm seeing another piece of functionality that should be available in axiom proper, needed for rom-mapper to stay reasonably simple
<snusnu> mbj: axiom needs to be able to rename wrapped and grouped tuples
<snusnu> mbj: in order to even get to a point where you can wrap or group, you need to join, for this join, you oftentimes need to rename attributes of the RHS (apart from the key to join on .. think: people.join(tasks) and both person and task has an attribute called :name)
<snusnu> so you'd most likely rename task.name to task_name in order for the join to work
<snusnu> now when you wrap :task, you end up with the wrapped attribute tuple having a :task_name slot
<snusnu> and when you want to *map* that to object land, you want it to be just :name
<snusnu> dkubb: ^^^^
cored has quit [Ping timeout: 272 seconds]
cored has joined #rom-rb
<cored> hi
<cored> is there a lib that implements the specification pattern for Ruby?
<snusnu> cored: i've never heard about that pattern
<cored> snusnu: hm
<cored> a friend of mine is building a gem for an implementation for that pattern
<snusnu> cored: sorry, i have no time to read through this now
<cored> snusnu: oh ok
<snusnu> mbj: i realize that both Axiom::Attribute::{Tuple, Relation} both expose #header which provides #rename, so implementing (Tuple, Relation)#rename should be not too big a deal .. what i wonder tho, is how much of it could be "automated" when doing #unwrap and #ungroup
<snusnu> mbj: in general, i have no real idea atm about a good api for that renaming
<snusnu> dkubb: ^^^^
<snusnu> mbj, dkubb: also, it seems to me that both Attribute::{Tuple, Relation} don't support CUD at this point, so i have no clear idea on how to (api wise) manipulate wrapped/grouped relations
<snusnu> mbj, dkubb: it seems to me tho, that inserting/deleting into a grouped attribute, and updating a wrapped attribute, should be entirely possible, and for it to work, the wrapped/grouped tuple(s) need to be unwrapped/ungrouped transparently
<mbj> snusnu: Need time to think about it. Nothing pops out while reading through your thoughts ;)
<mbj> snusnu: Advice, try to read axiom source code. Helped me a lot for similar problems.
<mbj> snusnu: Its very accessible.
<snusnu> mbj: wdym by nothing pops out? no error, no idea?
<snusnu> mbj: also, i read the axiom source code in that areas, otherwise i couldn't have made my claims :p
<mbj> snusnu: hehe, surry
<mbj> snusnu: no idea, no error, nothing: the void.
<snusnu> mwhah
<snusnu> nil
<mbj> snusnu, dkubb: We should have asked for bitcoins donations a year before ;)
<snusnu> f*** bitcoin
<snusnu> :p
<mbj> hehe
<snusnu> the currency, not necessarily the protocol ....
cored has quit [Ping timeout: 265 seconds]
cored has joined #rom-rb
cored has joined #rom-rb
<mbj> hehe
cored has quit [Ping timeout: 240 seconds]
cored has joined #rom-rb
cored has joined #rom-rb
vsorlov has joined #rom-rb
cored has quit [Ping timeout: 272 seconds]
cored has joined #rom-rb
adkron has joined #rom-rb
cored has quit [Ping timeout: 248 seconds]
cored has joined #rom-rb
cored has joined #rom-rb
<mbj> snusnu: capybara/poltergeist fucked my day: https://twitter.com/_m_b_j_/status/405742262820155392
<mbj> snusnu: version = `#{path} --version` WTF.
_br_ has quit [Ping timeout: 245 seconds]
_br_ has joined #rom-rb
cored has quit [Ping timeout: 272 seconds]
cored has joined #rom-rb
mkristian has joined #rom-rb
mkristian_ has joined #rom-rb
mkristian_ has quit [Client Quit]
cored has quit [Ping timeout: 252 seconds]
cored has joined #rom-rb
cored has joined #rom-rb
<dkubb> good morning
<dkubb> snusnu: to manipulate wrapped/grouped attributes you unwrap/ungroup, then apply the operation, then wrap/group them again. the optimizer can rewrite the queries so they are performed optimally
<dkubb> the RA books recommend against operations specifically on wrapped/grouped tuples because it would mean an explosion of operations.. every single operation would need 2 duplicates to work on wrapped and grouped tuples; and then they would only work to 1 level.. you'd need 2 level, 3 level ... 42nd level ;)
cored has quit [Ping timeout: 272 seconds]
<mbj> dkubb: makes sense! Thx.
<mbj> snusnu: pin
<mbj> snusnu: ping
<snusnu> dkubb: i see, and yeah, makes sense, also i don't mind doing the unwrap/ungroup inside #insert and the likes, then doing wrap/group again
<snusnu> dkubb: what are your thoughts on the renaming issue tho?
<snusnu> mbj: yo
<mbj> snusnu: lets do our "weekly" skype talk? Perfect time for me would be: NOW
<mbj> dkubb: Wanna join?
<mbj> snusnu: We can also set a HARD timebox like: sleep 1200 && killall sykpe ;)
<snusnu> mbj: i need a few more minutes to decide (with friends) wether we'll be going to a great hiphop show tonight ...
<mbj> snusnu: heh, no problem to do it later the week
<snusnu> if we decide against, i'd be up for a chat tho .. i just need some more time :)
<mbj> snusnu: ping me
<snusnu> will do
cored has joined #rom-rb
<dkubb> mbj: I can't, this is right in the middle of my workday :(
<mbj> dkubb: np
vsorlov has quit [Ping timeout: 252 seconds]
postmodern has joined #rom-rb
<postmodern> so im looking on mapping a PORO to JSON for storage, anyone know of decent libraries for this?
<postmodern> so far I found representable https://github.com/apotonick/representable#readme
<snusnu> postmodern: use ducktrap
<postmodern> snusnu, is ducktrap production ready?
<snusnu> postmodern: yeah
<snusnu> postmodern: it's api could/will be improved, in fact, inside the morpher branch, there's initial code for what will replace ducktrap, but current ducktrap is stable, and if you don't have shitloads of those mappings to write, updating to morpher will be a breeze
lfox has quit [Quit: ZZZzzz…]
<mbj> postmodern: ducktrap was 100% mutation covered at the time I released v0.1
<mbj> postmodern: You'd need to write custom node if your POROS dont have an anima compatible interface.
<postmodern> snusnu, mbj, yeah still find the user-facing API awkward
<mbj> postmodern: But this custom node is probably 40 loc.
<mbj> postmodern: +1
<postmodern> mbj, for example, why do I call success? shouldn't it just raise an exception?
<mbj> postmodern: bacause steering control flow via exceptions is a bad pattern when you process input from external sources (network).
<mbj> postmodern: Use Evaluator#run(input) to get an exception.
<postmodern> mbj, exceptions are perfectly fine for expressing errors
<postmodern> mbj, such as when malformed input has been submitted
<postmodern> mbj, it's an exceptional case
<snusnu> call #run then
<postmodern> mbj, or you might consider using throw/catch
<mbj> postmodern: they are not, if misused.
<snusnu> not meaning to be rude, but we will never ever resolve the viewpoints on what makes up an exception or not
<mbj> postmodern: begin; JSON.parse(input); rescue; JSONError; end # okay
<mbj> postmodern: BUT I saw code like this: def use_case(input); do_use_case_stuff; rescue JSONError; end
<mbj> but do_use_case stuff ITSELF delegated to another 3rd party API that raised the JSONError
<postmodern> mbj, i prefer to allow my exceptions to bubble up and get logged
<mbj> now you got the problem: Is this an malformed input? Or a "Deeper" problem.
<mbj> postmodern: Perfect. Use #run ;)
<postmodern> mbj, for your examples, perhaps a method that just returns nil or false on error might be better
<postmodern> mbj, if (output = trap.call(input))
<mbj> postmodern: nil might be a valid output.
<mbj> postmodern: I make 0 assumptions.
<postmodern> mbj, good point
<postmodern> mbj, i think the fact that you create an object, then the result is stored in it, strikes me as a smell
<postmodern> mbj, would prefer that the result be returned, maybe in a Result object
<postmodern> mbj, then you would check result.success? and result.output/result.error
<mbj> postmodern: its like resouce.valid?
<mbj> postmodern: typciall controller
<mbj> resource = Model.new(parmas) # I know this is crappy model should not know about coercions in my wold
<mbj> resource.valid?
<mbj> if resource.valid?
<postmodern> mbj, that way it's threadsafe/immutable
<mbj> steer control flow
<mbj> end
<mbj> Yeah
<mbj> postmodern: I put MUCH thought into ducktap API
<mbj> And I ran into all errors for my self.
<mbj> NIH has positive sites!
<postmodern> mbj, the current API isn't thread-safe, if you shared an evaluator between two threads
<mbj> postmodern: evaluators are frozen, DEEP frozen.
<postmodern> mbj, but they write to #output
<mbj> postmodern: there is no mutable state in ducktrap
<mbj> postmodern: no
<mbj> postmodern: Evaluators return result objects.
<mbj> evaluator = Ducktrap.build { crappy_dsl_here }
<mbj> result = evaluator.call(input)
<mbj> result.frozen? == true
<postmodern> mbj, ah your README example appears to be out of date
<postmodern> evaluator = Person::TRAP.call(p_hash)
<mbj> postmodern: it has a naming fuckup
<mbj> postmodern: the evaluator (tree) is like an AST
<mbj> that knows how to behave.
<mbj> So NOT an AST ;)
<mbj> postmodern: ducktraps internals are to complex, morpher will be much more thin, with even higher code reusage.
<postmodern> mbj, ah ok, so evaluator in your example should really be called result
<postmodern> mbj, ah interesting, haven't heard about morpher
<postmodern> mbj, at first i thought it was a typo of mutant ;)
<mbj> postmodern: no
<mbj> postmodern: The idea of morpher is the split into transoforming nodes and predicate nodes.
<mbj> postmodern: The conneciton is a single guard node.
<mbj> postmodern: connection between predicates and transforming nodes.
<mbj> postmodern: Also all evaluations of transforming and predicate nodes are (optionally) tracable.
<mbj> postmodern: So eighter you execute that stuff as fast as possible, get an exception or result.
<mbj> postmodern: OR you get a result object (called evaluation in morhpher) that you can navigate.
<postmodern> mbj, ah cool
<mbj> postmodern: vanguard will just be a dsl frontend.
<mbj> postmodern: validations are nothing more like a predicate with history
<mbj> postmodern: Because I have an AST as IR, I can also compile to pure ruby. (Not needed AFAIK, big methods arent jitted).
<mbj> postmodern: Or transform it to JS ;)
<mbj> postmodern: For syncing form models in ruby with JS validations.
<postmodern> mbj, seems like overkill for a simple Hash -> PORO API
<postmodern> also you guys, ASTs are not hammers :)
<mbj> postmodern: All transformers can generate an invers.
<mbj> postmodern: We have a subset of all domains where the nails currently fit ;)
<mbj> postmodern: So if you need PORO => JSON and JSON => PORO ducktrap is your friend.
<mbj> postmodern: If the DSL wasnt to crappy, I'd totally suggest using it for the most simpliest use cases.
<mbj> postmodern: Also ducktrap evaluators are composable.
<mbj> postmodern: if poro-a has a member of type poro-b you could reuse that evaluator.
<mbj> postmodern: For my JSON APIs I'll use a hybrid evaluator.
<snusnu> that's how the rom-mapper ducktrap branch does it's thing btw, and is able to map arbitrarily nested EV/ECs with virtually no loc
<mbj> postmodern: First it'll use the nontracking strategy. If there is an error rescued, use the tracing strategy to find and report where.
<mbj> postmodern: I pretty print all ducktrap transformation failures to the application log already.
<mbj> postmodern: VERY handy on debugging.
<snusnu> letting ducktrap loose on the params passed to any (rack) app is the single most coolest thing i've done recently
<mbj> yeah, it directly reflects the name choise
<mbj> catching the duck typing traps ;)
<mbj> choice
<mbj> postmodern: You ever exploited an app via "duck typing"?
<snusnu> try to send me something invalid? you're out, immediately, and i see what you tried to do
<mbj> postmodern: ducktrap is your defense. I bypassed some checks that simply where like "params['baz'].length == 1"
<mbj> There are 3 types you can submit in params that can possibly pass this check: String#length, Array#length, Hash#length
<mbj> Where the programmer might just wanted to test a specific EV is present.
<mbj> Or a specific EC has size 1
<mbj> ducktrap was meant as an XSD for JSON/YAML/rack-params
<mbj> postmodern: fixed README, THX!
<postmodern> mbj, was talking about things like ducktrap to some security researchers, and they quiped that we are essentially re-creating Types in a dynamic language
<mbj> postmodern: nope, we are recreating a vm with tracing evaluation.
<mbj> postmodern: even worse.
<postmodern> haha
<mbj> postmodern: BUT for GOOD.
<mbj> postmodern: For a duckypting language you MUST typecheck data *once*
<postmodern> and im sure it's performance will be impeccable ;)
<mbj> postmodern: Data from the outside ;)
<mbj> postmodern: It was *fast enough*. Also modern GCs can easily deal with lots of small objects that will not reach the permanent generation.
<mbj> postmodern: The hybrid approach will only create lots of objects in case of error.
<mbj> postmodern: And generally: Lets deal with correctnes first ;)
<postmodern> hopefully ruby 2.1's generational GC will make a lot of what ROM is doing more performant
<snusnu> this is a provocative statement, but: the ones that really have to care about perf, should just get involved in dev, for the rest of us, we want correctness
<mbj> postmodern: You have been bit by duck typing when someone made a validation type compatible object appearing somewhere it shouldnt appear?
<mbj> abstract description of that class:
<mbj> input = deserialize(network_stuff)
<mbj> input.foo == some_expectation # now assuming its a Foo
<mbj> use_for_something(input) # fucked it was actually a Bar and you could exploit this fact.
<mbj> because Foo and Bar shared a property that could be validated.
<mbj> If so: Think about ducktrap.
<mbj> If not: Think about ducktap style libs even MORE ;)
<mbj> postmodern: duck typing based programming uses "do not programm defensively" mantra quite heavly.
<mbj> Wich is totally OKAY.
<mbj> But if you carefully read that erlang recommendation: It reads like: "Trust your input once it entered your programm successfuly, AFTER it has ben checked".
<postmodern> but you need a guard at the front of your application
<mbj> postmodern: Thats what ducktrap is for.
<snusnu> you can only program offensively if you can trust your data
<mbj> postmodern: Just AFTER the deserialization.
<mbj> You need to assure type validility just after deserialization.
<postmodern> mbj, i still like the idea of building the validations into the parser
<snusnu> i know i'm in ranting mode, but, if a business has to care about perf, it *has* the resources to provide perf fixes … i don't see *any* reason why *i* would code for perf foremost
<mbj> postmodern: I still like to build a validator that is correct and works for ALL parser outputs ;)
<postmodern> mbj, but ducktrap is probably much easier to sell developers on
<mbj> postmodern: Patch YAML / JSON / rails.params to support type validations?
<mbj> nope
<mbj> use a generic layer for that.
<mbj> And if you did so: Just transform your ankward hash of hash of array of hashes thing to a DTO.
<mbj> Because code that passes that primitive tree of primitives around and accesses it at multiple layers is ankward to refactor.
<mbj> snusnu: We should tell postmodern about our substation thing ;)
<snusnu> hehe
<snusnu> it currently sucks a bit, mostly because the readme is as outdated as one can be
<snusnu> and it needs another refactoring round which i currently have no time for
<snusnu> fwiw, the general idea in the readme still applies, but the api shown there is completely outdated, also naming in general
<snusnu> bbiab
snusnu has quit [Quit: Leaving.]
snusnu has joined #rom-rb
<mbj> snusnu: wb
cored has quit [Ping timeout: 272 seconds]
_jesse_ has joined #rom-rb
jgaskins has quit [Quit: Leaving]
<snusnu> is the memoizable gem already usable?
<mbj> snusnu: AFAIK close.
<mbj> snusnu: close to be useable
<snusnu> and it can be used in mutable classes, right`
<snusnu> ?
<snusnu> mbj: fwiw, it is usable, and works with mutable classes, great
<snusnu> mbj: any quick pointers for further drying up of the pushed up methods?
<snusnu> mbj: maybe in the form of a commit?
<snusnu> lol
jgaskins has joined #rom-rb
cored has joined #rom-rb
cored has joined #rom-rb
<mbj> snusnu: gona go to sleep
<snusnu> fair enough
cored has quit [Ping timeout: 260 seconds]
<mbj> snusnu, dkubb, postmodern: cu
mbj has quit [Quit: leaving]
adkron has quit [Ping timeout: 265 seconds]
bf4 has quit [Quit: leaving]
kenphused has quit [Ping timeout: 246 seconds]
snusnu has quit [Quit: Leaving.]
snusnu1 has joined #rom-rb
cored has joined #rom-rb
snusnu has joined #rom-rb
snusnu1 has quit [Ping timeout: 246 seconds]
mkristian has quit [Quit: bye]
breakingthings has quit []