I'm using the Ruby 1.9 Ripper library to analyze specific parts of a source code by building it's sexp tree. From what I know, Ripper just uses a lexer / parser to do this.
Is it safe to run Ripper on a user submitted code?
Since it does not actually evaluate any code, yes it is safe.
If you are talking about taking those s-expressions and evaluating them, then most certainly the answer seems to be: Not without cleaning it first. That cleaning process could be especially tricky though.
Related
Can Anyone point Me to a tool to detect unused code, objects, methods, parameters, etc., in Ruby code?
I saw nitpick but it does not seem to give me the coverage I want. I also checked laser and reek but their respective gems seem to have issues which prevent them from running.
I thought at one point the Ruby binary had a mode which would detect unused constructs but I do not seem to be able to find it.
It might help if we had a little more context in how you want to "detect unused code" - is this code coverage of your tests you're looking into? Otherwise, how would you know from run to run whether you hit all the use cases? Or are you looking for a statistical "heat map" of coverage over time for e.g. performance reasons?
In any case, for code coverage while testing I use SimpleCov - it uses Ruby 1.9's built-in Coverage library with some nice sugar on top.
You can also use a mutation tester that mutates your code. In case the mutation tester can delete a construct without your tests noticing. You found an unused construct.
I know two mutation testers for ruby:
Heckle
Mutant
Disclaimer, I'm the author of mutant.
Depending on your setup, your ruby version, spec layout, test framework heckle and or mutant can do the job for you.
Here you can see mutant in action: http://ascii.io/a/1707
JetBrains RubyMine http://www.jetbrains.com/ruby/quickstart/index.html
I have no idea how to build S-exp.
I want to do it, because I need to build AST for my langauge.
At the beginning I used RubyParser to parse it to sexp then code gen.
But it must be ruby's subset I think.I cant define the language what I want.
Now I need to implement parser for my language.
So anyone could recommend any ruby tool that building AST for S-expression ?
Thanks!
It is not very clear from your question what exactly do you need, but simple Google search gives some interesting links to check. Maybe after checking these links, if they are not the answer to your question, you can edit question and make it more precise and concrete.
http://thingsaaronmade.com/blog/writing-an-s-expression-parser-in-ruby.html
https://github.com/aarongough/sexpistol
You might try the sxp-ruby gem at http://github.com/bendiken/sxp-ruby. I use it for SPARQL S-Expressions (SSE) and similar methods for managing Abstract Syntax Trees in Ruby.
Maybe you could have a look at this gem named Astrapi.
This is just an experiment :
describe your language elements (concepts) in a "mm" file (abstract syntax)
run astrapi on this file
astrapi generates a parser that is able to fill up your AST, from your input source expressed in s-expression (concrete syntax of your concepts).
I have put a modest documentation here.
A parser I'm looking for should:
be Ruby parsing friendly,
be elegant by rule design,
produce user friendly parsing errors,
user documentation should be available in volume more than a calculator example,
UPD: allowing to omit optional whitespaces writing a grammar.
Fast parsing is not an important feature.
I tried Citrus but the lack of documentation and need to specify every space in rules just turned me away from it.
Treetop
Ragel
Or in case you want to parse Ruby itself:
parse_tree and ruby_parser
Edit:
I just saw your last comment about needing a subset of Ruby for your project, in that case I'd also recommend having a look at tinyrb.
This question already has answers here:
Encoding Ruby on Rails code?
(5 answers)
Closed 4 years ago.
Is there a ruby obfuscator or "compiler"?
There are a few options, like RubyScript2Exe or AllInOneRuby. However, all obfuscators of interpreted languages tend to have a serious flaw: they usually don't understand more sophisticated metaprogramming techniques.
That is, they can't necessarily tell that something like foo.send(:bar, ...) is an invocation on the bar method in a completely different library, or that eval("require %w{abc def ghi}") means to require three different libraries. These are trivial examples -- things get much more complex when you throw method_missing and its ilk into the mix.
When an obfuscator encounters this sort of code, it will dutifully compile the appropriate instructions, but it may not know to also include certain libraries or other code from elsewhere. That can cause serious issues, since the dynamically included or required will not be available at runtime in a statically linked executable.
Unfortunately, many gems and libraries use sophisticated metaprogramming techniques. You'll likely get into trouble here if you try to use obfuscation and expect your program to have the same behavior. Worse still, because there are so many levels of indirection, if a bug occurs in the obfuscated version, you may never know what exactly happened or how to reproduce it.
Depending on what you are trying to do, there is a Gem that will allow you to create a C extension from a Ruby script which can then be used as a require inside your Ruby app. Its called ruby2cext. It will obfuscate all of your code into C and the you can require the .so in a separate Ruby script and it will function like a normal Ruby script.
RubyScript2Exe - http://www.erikveen.dds.nl/rubyscript2exe/
Most of the code I write is in Ruby, and every once in a while, I make some typo which only gets caught after a while. This is irritating when I have my scripts running long tasks, and return to find I had a typo.
Is there an actively developed lint tool for Ruby that could help me overcome this? Would it be possible to use it across a system that works with a lot of source files, some of them loaded dynamically?
Take this snippet as an example:
a = 20
b = 30
puts c
To win bounty, show me a tool that will detect the c variable as not created/undefined.
ruby -c myfile.rb will check for correct Ruby syntax.
Reek checks Ruby code for common code smells.
Roodi checks Ruby code for common object-oriented design issues.
Flog can warn you about unusually complex code.
[Plug] If your project is in a public Github repository, Caliper can run the latter three tools and others on your code every time you commit. (Disclaimer: I work on Caliper)
You could give Diamondback Ruby a try. It does a static typecheck of Ruby code, and will thus blame you for using an undefined variable.
While DRuby is an ongoing research project, it already works quite well for small, self-contained Ruby scripts. Currently, it is unable to analyze much of the Ruby standard library “out-of-the-box”. Currently they are working toward typing Ruby on Rails (see their most recent papers).
RubyMine (http://www.jetbrains.com/ruby) does the trick:
alt text http://img707.imageshack.us/img707/5688/31911448.png
None of the below will do all the analysis that RubyMine does.
NetBeans Ruby pack
Aptana RadRails
gVIM (with syntastic plugin by scrooloose)
Each of these has the capacity to identify syntax errors such as wrong number of parentheses, too many defs, ends, braces, etc. But none will identify invalid method calls the way RubyMine does.
Here's why: it's difficult.
Since Ruby is extremely dynamic (and methods like 'c' could easily be generated on the fly), any editor that tries to identify non-existent variables/methods would need to have a large part of the entire evironment loaded and multiple program flow paths constantly tested in order to get accurate 'validity' results. This is much more difficult than in Java where almost all programming is static (at least it was when I dropped that hat).
This ability to easily generate methods on the fly is one of the reasons the community holds testing to such high esteem. I really do reccomend you try testing as well.
Have a look at RuboCop. It is a Ruby code style checker based on the Ruby Style Guide. It's maintained pretty actively and supports all major Ruby implementations. It works well with Ruby 1.9 and 2.0 and has great Emacs integration.
Yes. Test::Unit
Ok, I know you already know this and that in some sense this is a non-helpful answer, but you do bring up the negative consequence of duck typing, that there kind of is (at this time) no way around just writing more tests than something like Java might need.
So, for the record, see Test::Unit in the Ruby Standard Library or one of the other test frameworks.
Having unit tests that you can run and rerun is the best way to catch errors, and you do need more of them (tests, not errors :-) in dynamic languages like Ruby...
nitpick might be what you're lookng for.
With this code:
class MyString < String
def awesome
self.gsub("e", "3").gsub("l", "1").uppercase
end
end
puts MyString.new("leet").awesome
... it outputs:
$ nitpick misspelling.rb
*** Nitpick had trouble loading "misspelling.rb":
NoMethodError undefined method `uppercase' for "133t":MyString
Nothing to report boss! He's clean!
Have not used it yet, but sounds promising (will update when I've tested this).
https://github.com/michaeledgar/laser
Static analysis and style linter for Ruby code.
Pelusa is nice, but is working in rubinius only. This shouln't be a proplem for people familar with RVM though.
avdi#lazarus:~$ irb
>> a = 20
=> 20
>> b = 30
=> 30
>> puts c
NameError: undefined local variable or method `c' for main:Object
from (irb):3
>>
There ya go, the tool is called "IRB". Do I get the bounty?
I'm only half joking. I wrote this second answer to hopefully drive home the point that in Ruby, if you want to know that something is defined or not, you have to run the code.