<snusnu>
skade: got a minute for a rather general question?
<skade>
snusnu depends on the question :) feel free to ask
<snusnu>
skade: heh ok, i was wondering, since yesterday you mentioned that virtus knows about the type info … do you actually think that it's "good" to make a ruby (domain) object / "poro" enforce typing? i mean, ruby by itself doesn't ...
<snusnu>
skade: i guess i'm actually thinking that's wrongish .. a pure ruby object, would never know/enforce the type of any attributes
<skade>
it actually doesn't
<snusnu>
right, good point .. the coercion is externalized too
<snusnu>
i guess
<skade>
the nice thing about virtus is that it coerces at certain boundaries (construction, getting, setting, etc)
<snusnu>
right ok, then it's the DSL that i find somewhat misleading
<skade>
but if you really want to, you can set the value to anything you want
<snusnu>
i mean, specifying the type in the domain object itself
<skade>
well, considering how much code I have seen that does hold that information implicitely, i thing virtus is a huge step forward
<skade>
yep, I think thats valid
<snusnu>
oh absolutely, virtus is cool, i just came across this while spiking a rom compatible mapper that operates with ducktrap under the hood, and anima
<snusnu>
imo anima has the advantage of NOT tying the typing info to the domain object itself
<snusnu>
the fact that coercion happens externally, is clear, delegated to ducktrap
<skade>
depends on what you want to do
<snusnu>
to get that straight again, anima's DSL doesn't mingle type info into the domain object
<skade>
i often have virtus as a core domain description without too much around.
<snusnu>
yeah absolutely, it always depends .. my current thinking mostly evolves around mapping usecases tho
<skade>
so basically, there is a tree of virtus objects to describe "do what you want, but please make sure that it turns out to be _this_"
<snusnu>
heh right
<skade>
e.g. I have a client that has three different data channels
<skade>
frontend<->backend (API), backend<->database and a third channel that pushes stuff to the databse
<skade>
so we used virtus as a contract that describes what objects those three layers speak about
judofyr has quit [Remote host closed the connection]
<snusnu>
sounds very reasonable, i guess my main "complaint" is DSL related anyway, and too tied to the specific usecase of mapping tuples
<snusnu>
i like stuff to be explicit, even if that comes at the cost of conciseness sometimes
<skade>
well, virtus does add a few other things, for example the ability to inspect the data graph for type info
judofyr has joined #rom-rb
zekefast has joined #rom-rb
snusnu has quit [Ping timeout: 245 seconds]
<judofyr>
skade: are you working on ROM?
<skade>
judofyr: nope, just using virtus a lot
<judofyr>
ah
<skade>
look out for dkubb, mbj or snusnu
<judofyr>
actually, you might be the perfect guy for discussing this
<skade>
:D
<skade>
then just ask away
snusnu has joined #rom-rb
<judofyr>
here's the idea: when you get a model from the database it should be "frozen"
<judofyr>
I dislike the whole "partially initialized" issue
<judofyr>
or
<judofyr>
u = User.find(10); u.name = 'foo'; # u is in a really odd state now
<judofyr>
the fact that you can change the model to something completely invalid feel a bit ood
<judofyr>
odd*
<judofyr>
so the idea was: u = User.find(10); u.name = 'foo' will raise an exception
<skade>
you mean, you don't like the dirty state?
<judofyr>
yes
<judofyr>
because the object represents something really odd: it has some content that comes from the database, and some content that you have set
<judofyr>
you can trust the content/data from the database
<judofyr>
but the content/data that you set might be crap
<judofyr>
(e.g. foreign key errors)
<judofyr>
or NOT NULL issues
<skade>
I see
<judofyr>
so I was thinking: why not move updates to the session manager?
<judofyr>
instead of updating the object and then tell the session manager to "save everything that has changed"
<judofyr>
you do: session.update(model, :name => 'foo')
snusnu has quit [Client Quit]
<judofyr>
and it will *first* update the database and after that succeeds, it will update the model
<judofyr>
(this might not fit into what ROM is doing today, but I feel like this is the best community to discuss this idea)
<skade>
i do actually like the idea
<skade>
I do miss the seperation of models and their storage a lot in activerecord (and similar)
<skade>
expressing the update as a database operation seems like a nice way to model things
<judofyr>
it might require a completely different style though
<judofyr>
in ActiveRecord you often have methods inside a model that touches the database
<skade>
thats true
<judofyr>
class User; def verified!; self.verified_at = Time.now; save end end
<judofyr>
it means that model objects pretty much becomes read-only
<judofyr>
with ROM today you can do something similar as above, just without the call to #save.
<skade>
I didn't have a through look at ROM in that regard at the moment, so I cannot comment on that
<judofyr>
with this new approach this is not possible
<judofyr>
I think that's the biggest issue with this new approach: there's now two different ways of updating the model. if you're working with model objects that are not backed by a database, you use the "regular" interface. if they are backed by a database, you need a completely different interface.
<judofyr>
that might prove difficult
<skade>
on the other hand, it makes the database interaction explicit
<judofyr>
yeah, and having read-only models *is* nice
<judofyr>
it means you can trust it
<skade>
and i am mostly against implicit db interaction
<judofyr>
other idea: all model objects should be "frozen" in initialize
<judofyr>
(I say "frozen" because I think it's only important that attributes are frozen. you might use other instances variables for caching and so on)
<skade>
well, at least in the case of virtus, that distinction might not be easy to make
mbj has joined #rom-rb
<judofyr>
true
<skade>
but fully freezing and copying on change might also be an interesting idea
<skade>
or, alternatively, properly model changes as an object. Considering that many databases nowadays prefer sparse updates, that might even have real advantages
<skade>
"real" in the sense of "maps good to how it works anyways"
<mbj>
hi
<skade>
hi! :)
knowtheory has quit [Quit: Computer has gone to sleep]
<judofyr>
mbj: did you see backlog?
kleech has quit [Remote host closed the connection]
kleech has joined #rom-rb
zekefast has quit [Quit: Leaving.]
zekefast has joined #rom-rb
kleech has quit [Ping timeout: 246 seconds]
knowtheory has joined #rom-rb
mbj has quit [Ping timeout: 260 seconds]
mkristian has quit [Ping timeout: 272 seconds]
judofyr has quit [Remote host closed the connection]
zekefast has quit [Quit: Leaving.]
mkristian has joined #rom-rb
zekefast has joined #rom-rb
mkristian has quit [Ping timeout: 252 seconds]
lgierth has joined #rom-rb
lgierth has quit [Quit: Ex-Chat]
breakingthings has quit []
breakingthings has joined #rom-rb
mbj has joined #rom-rb
mbj has quit [Ping timeout: 256 seconds]
mbj has joined #rom-rb
kleech has joined #rom-rb
zekefast has quit [Quit: Leaving.]
mbj has quit [Ping timeout: 264 seconds]
kleech has quit [Read error: Connection reset by peer]
kleech has joined #rom-rb
knowtheory has quit [Read error: Operation timed out]
knowtheory has joined #rom-rb
zekefast has joined #rom-rb
kleech has quit [Remote host closed the connection]
skade has quit [Ping timeout: 272 seconds]
breakingthings has quit []
knowtheory has quit [Quit: Computer has gone to sleep]
knowtheory has joined #rom-rb
knowtheory has quit [Ping timeout: 245 seconds]
cored has joined #rom-rb
<cored>
hello
<cored>
dkubb: are you around ?
<dkubb>
cored: yup
<cored>
dkubb: following your next advice at the moment
<cored>
I thought in something now, having an internal helper class which runs flay
<cored>
because the call method is needing the flay instance not exactly the self command
<cored>
but probably what I should do is to make wrapper internal command helper methods which expose flay internal api
<cored>
what do you think?
<dkubb>
you could always have private methods your object uses
<dkubb>
for me, the interface of private methods is more wide open. it exposes what the object needs and the optimal input/output types
<cored>
I see
<cored>
also it is normal that mutant return a bunch of warnings ?
<cored>
pointing it to a particular class
<dkubb>
yeah, it has a few warnings for an ivar
<cored>
I see
<dkubb>
I think mbj knows about it, but feel free to poke him if you see him ;)
<dkubb>
they're warnings in unparser or mutant, right?
zekefast has quit [Quit: Leaving.]
<cored>
yes
<cored>
still thinking a little bit on more refactoring regarding the query/command distinction
<cored>
parting from the fact that run_flay looks like a command method in all it's glory I switched the return value to be self
<cored>
now that's pointing me to the direction of having a similar interface as flay itself inside the Tasks::Flay class or having an accessor method for the flay instance which I'm considering to be the better path
knowtheory has joined #rom-rb
cored has quit [Ping timeout: 245 seconds]
<dkubb>
sure, and think whether or not you need to even expose the flay instance