
Show HN: Laboratory, a Python port of GitHub's Scientist library for refactoring - buttscicles
https://github.com/joealcorn/laboratory
======
nubs
Here's some other ports of Scientist I've come across as well:

PHP

[https://github.com/LartTyler/Analyst](https://github.com/LartTyler/Analyst)

Javascript

[https://github.com/trello/scientist](https://github.com/trello/scientist)

[https://github.com/Runnable/scientist](https://github.com/Runnable/scientist)

[https://github.com/jirwin/labrat](https://github.com/jirwin/labrat)

~~~
taspeotis
.NET

[http://haacked.com/archive/2016/01/20/scientist/](http://haacked.com/archive/2016/01/20/scientist/)

------
lasdfas
I imagine this can only work on getters? How do you use this when code makes
state changes?

~~~
chucksmash
From Github's Scientist [1]:

Because `enabled?` and `run_if` determine when a candidate runs, it's
impossible to guarantee that it will run every time. For this reason,
Scientist is only safe for wrapping methods that aren't changing data.

When using Scientist, we've found it most useful to modify both the existing
and new systems simultaneously anywhere writes happen, and verify the results
at read time with `science`.

[1]:
[https://github.com/github/scientist/blob/master/README.md#de...](https://github.com/github/scientist/blob/master/README.md#designing-
an-experiment)

------
jack_jennings
Before clicking the link I wondered how this would translate the block-based
Ruby API into Python. Using Python's with statement is quite nice here, I
think.

The with statement is one of my favorite additions to the language. It's a
really flexible syntax to encapsulate control flow, exceptions, necessary
cleanup steps… etc. etc.

~~~
chronial
I would argue that python provides even simpler syntax to enable functionality
like this.

    
    
      @experiment.with(new_function)
      def old_function()
          ...

~~~
shoyer
Agreed -- a decorator seems like a much cleaner way to handle this.

~~~
msellout
A decorator must be applied to a function or class, whereas a context manager
can wrap an arbitrary section of code. So, it depends on how you want the tool
to be used. I don't think there's a clear best design.

~~~
buttscicles
This was my thought as well, and it's also a bit more awkward if your function
signatures differ. Luckily they aren't mutually exclusive and it should be
easy to implement a decorator version.

------
ByteJuggler
Another Python one:
[https://github.com/staticshock/scientist.py](https://github.com/staticshock/scientist.py)

------
agentultra
Cool! Thanks for the tool!

> Imagine you've implemented a complex caching strategy for some objects in
> your database and a stale cache is simply not acceptable.

I hope you have a formal specification of that cache. That will help ensure
your design is correct in the first place before you even get to running it in
code.

I shall be playing with this soon. Cheers!

------
jonathankoren
Python? Isn't Python dying? ;)
[https://news.ycombinator.com/item?id=11100251](https://news.ycombinator.com/item?id=11100251)

