I see, thanks for this clarification on Base. I switched over to doing explicit import because I was running into these dispatch issues, now I understand better how to extend Base functions.
I wasn't aware that methods on custom types are considered part of the type - I thought if the type definition didn't change then the methods would still be able to operate on them. Is this not the case? It certainly makes sense that I would have to re-run the whole code if the type field definition changes. I suppose the "best practice" here is to train myself out of the bad software engineering habits (i.e. laziness) I have developed while using ipython notebook. If I'm writing types and methods, I should write proper test code to go along with it and then include as suggested above. Thanks for your swift responses! On Monday, June 1, 2015 at 2:47:40 PM UTC-4, Scott T wrote: > > First, since you're extending Base functions (start, next, done), you can > alter the top slightly: > import Base: start, next, done > export ResultSet > > Now you can drop the `mt` from `mt.start`, since you are just calling a > Base function which now has a method appropriate to your type. You can see > this if you do methods(start) before and after running that cell - you will > have added an extra method. This will let you use your new type as an > iterator: for example, in constructions like > for x in some_result_set > do_stuff_with(x) > end > it will work just like any other standard iterator, which is pretty > awesome. > > After doing this, you should hopefully find that you can call `start` on > your ResultSet even after re-importing the mt module. But there's a big > problem with this: you will be using the "old" version of `start`. For > example, changing > start(x::ResultSet) = 2 > then re-running that cell and doing > start(HD1_HDvC_batch) > will still give you 1. That's because the ResultSets you had lying around > are still of the "old" type. They can't be automatically updated when you > reload the module by re-running that first cell, since the compiler has no > guarantee that you haven't fundamentally changed the way a ResultSet works. > > I think you'll need to re-create the ResultSets that you are using, either > in the mt module or in a cell that you run immediately afterwards. Then > they will be of the new type and work with the new functions. I don't think > this plays so nicely with the idea of running incremental analyses, since > you need to make a new ResultSet instead of just adding results to an old > one, so others may be able to offer better solutions on this if that's what > you need. > > Cheers, > Scott T > > On Monday, 1 June 2015 17:54:11 UTC+1, Adam Labadorf wrote: >> >> Hi, >> >> I am using julia 0.3.8 + IJulia, and have been using ipython notebook for >> sometime to perform my research activities. For my current project, I >> define and export a number of types and methods wrapped in a module in one >> of the cells, import the module, and refer explicitly to those types and >> methods elsewhere in the notebook. I have found that redefining/reimporting >> the module does not seem to work as expected (code excerpt only): >> >> module mt >> >> export ResultSet, start, next, done >> >> type ResultSet >> models::Array{Any} >> sample_inds::Array{Int64} >> failed::Array{Int64} >> num_fails::Int64 >> end >> start(x::ResultSet) = 1 >> next(x::ResultSet,i::Int64) = (x.models[i],i+1) >> done(x::ResultSet,i::Int64) = (i == length(x.models)+1) >> >> end >> >> import mt; >> >> It works the first time after kernel restart: >> >> mt.start(HD1_HDvC_batch) >> >> 1 >> >> >> Later, after editing and rerunning the code: >> >> # model_batch is a ResultSet object >> state = mt.start(model_batch) >> >> `start` has no method matching start(::ResultSet) >> while loading In[10], in expression starting on line 7 >> >> >> Eventhough: >> >> >> methods(mt.start) >> 1 method for generic function *start*: >> >> - start(x::*ResultSet*) at In[9]:33 >> >> >> I have to restart the kernel basically every time I change any of the types >> or their methods. This is currently just an annoyance, but when I start >> running larger analyses in IJulia it will become prohibitive. I am aware of >> the issues with redefining types in the main namespace of an active kernel >> REPL, the workspace() function seems to be practically the same as a kernel >> restart, and defining my types in a module in a cell doesn't seem to fix the >> resolution issues. To my question: >> >> Is there currently a best practice for using IJulia in this way when >> developing with custom types? At least one that does not require a kernel >> restart every time? >> >> I'm still pretty new to julia, so if I am doing anything incorrectly here >> I'm keen to learn. I'd love to use julia+IJulia exclusively for my work as I >> once did for python, but it seems there are some of these issues that are >> presently a barrier to doing that effectively. Does anyone have any >> suggestions? >> >> Thanks. >> >> >>