Hacker News new | comments | show | ask | jobs | submit login

I've been wanting something like this for Ruby for some time now. Since it's dynamically typed and ridiculously easy to monkey-patch, Ruby is a much harder challenge than C++. The two best efforts I have found are Diamondback Ruby (http://www.cs.umd.edu/projects/PL/druby/) and Laser (http://carboni.ca/projects/p/laser)...but they mostly try to add static type-checking to Ruby code. After looking at these I implemented a contracts library for Ruby (https://github.com/egonSchiele/contracts.ruby) to get myself some better dynamic checking. The next step is to use the annotations for the contracts library to do better static code analysis. One thing I'm working on is generating tests automatically based on the contract annotations. But I've got a long way to go : ( If anyone knows about other projects that are working on static analysis for Ruby I'd be very interested in hearing about them!



Looked at your Contracts library for Ruby. I was just thinking yesterday about starting a project like this! Some thoughts:

- I like that the contracts are right there in the code and not in a separate file.

- The actual Contract methods only run once upon loading each class, so they don't cause a performance hit. I'd like a way to make them all noops (so they don't add any instrumentation) when running in "production".

- My thought is that if you can define pre- and post-conditions as you're doing, then you can cut out a lot of the checks in your tests, so that as long as the tests exercise the code, you can rely on the post-conditions to do quite a bit of the validation. Plus you're validating outputs all over the place constantly, so you'd probably catch edge cases you never even expected.

- I'm disappointed that your system seems to offer little more than type checking (unless I'm mistaken). I'd like something that gives me true pre- and post-conditions: basically passing a block of Ruby code for each one, with common idioms abbreviated so I don't need to write a whole block if the conditions are simple.

Good luck on the project!


Great thoughts!

> I'd like a way to make them all noops

Sure! There's a default failure callback that gets called when a contract fails. You can just clear this callback in prod:

    if ENV == PRODUCTION
        class Contract
          def self.failure_callback(data)
            # blank
          end
        end
    end
> I'm disappointed that your system seems to offer little more than type checking

Nay! You can write your own contracts to do anything you want. So yes, lambdas are allowed in contracts:

    Contract lambda { |x| x.is_valid_email? } => Bool
    def save_email(email)
      # save an email
    end

> with common idioms abbreviated

I provide some common idioms already, but you can make your own abbreviations:

    ValidEmail = lambda { |x| x.is_valid_email? }

    Contract ValidEmail => Bool
    def save_email(email)
Let me know if you have any other questions :)


Thanks for the clarifications!


A couple that I know of which are based on the security side of things are Brakeman (https://github.com/presidentbeef/brakeman) and Scanny (https://github.com/openSUSE/scanny) on the open source side. On the commercial side I know Checkmarx covers rails (http://www.checkmarx.com/), amongst other languages


Wow, these are really cool. Thanks!




Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | DMCA | Apply to YC | Contact

Search: