ParseTree will not work with ruby 1.9. Why? - ruby

As per this parsetree will not work in ruby 1.9 . I do not have computer science background but have been programming for a few years. Can someone explain in a little extra detail why parsetree will not work in ruby 1.9.

The ruby 1.8 interpreter constructed and then walked over an abstract syntax tree, whereas the ruby 1.9 interpreter is bytecode based. Therefore there is no AST available at runtime for parsetree to work with.

ngty has published a gem, called sourcify, that provides a lot of ParseTree's functionality in Ruby 1.9.
Since he couldn't use the AST, he wrote an sexp parser that works most of the time. Sometimes you have to give it some help, for example by telling it which Proc the code is attached to:
## The old ParseTree way
# proc.to_ruby
## The sourcify way - but may raise NoMatchingProcError or MultipleMatchingProcsPerLineError
# proc.to_source
## The sourcify way - giving :attached_to a symbol to help it find the correct Proc
proc.to_source :attached_to => :name_of_proc
Here's a longer explanation of how we replaced ParseTree when we migrated to Ruby 1.9.

ParseTree appears to be dead due to some changes internally to Ruby 1.9, as per this link:
http://blog.zenspider.com/2009/04/parsetree-eol.html
Though, it may be that some people will come up with some workarounds for part of it.

Related

Can I write ruby 2.3.7 scripts that are backward compatible with 1.8.7?

Up till now, I've been writing all my scripts in POSIX shell so that I can run them on all the machines I use (macOS, various Linuxes, FreeBSD). I like to have a unified experience where I can pull down my dotfiles from git, and have all my settings and scripts ready to go.
However, POSIX shell is a really irritating language, and I've been considering switching to Ruby for my scripting needs. Unfortunately before I even got started, I realized that macOS ships with Ruby 2.3.7, and one of the machines I often need to use only has Ruby 1.8.7. It's a school machine for which I do not have sudo access, so I can't install a later version of Ruby.
TL;DR
Is it possible to write Ruby scripts that will run on both 1.8.7 and 2.3.7 (and hopefully everything in between)? Is there a set of guidelines I can follow that will help me avoid incompatible language features?
Yes, it is possible, provided you restrict yourself to the intersection of the language and library features of Ruby 1.8.7, Ruby 2.3.7, and everything in between.
The last big break of backwards-compatibility was the jump from Ruby 1.8 to Ruby 1.9. String handling was completely changed, so anything to do with text processing, you need to be very careful.
Of the top of my head:
In Ruby 1.8, strings are considered to be a sequence of bytes. In Ruby 1.9. strings are a factory for different iterators, iterating in terms of code points, characters, or bytes.
Therefore, in Ruby 1.9, strings are no longer Enumerable.
Indexing into a string will return an Integer in Ruby 1.8 and a single-character String in Ruby 1.9.
Character literals (e.g. ?a) will evaluate to an Integer in Ruby 1.8 and a single-character String in Ruby 1.9.
In Ruby 1.8, all strings are assumed to be in the same encoding (usually ASCII, but can be changed to a very limited set, namely UTF-8 and a couple of Asian encodings). Ruby 1.9 is fully encoding-aware, each string has its own separate encoding, each I/O stream has two encodings (an internal one and an external one) and each source file has a separate encoding.
Your best bet might be to restrict yourself to use only what is specified in the ISO Ruby Language Specification. The spec was specifically written so that all existing Ruby implementations at the time (MRI, YARV, IronRuby, JRuby, MacRuby, Rubinius) would automatically be compliant, which basically means that the spec only specifies the minimal required subset of the intersection of Ruby 1.8.6, Ruby 1.8.7, and Ruby 1.9.0.
Since there haven't been any backwards-incompatible changes since then, you can be assured that your code will work on all versions from Ruby 1.8.6 up to (but excluding) 3.0, and on all ISO-compliant Ruby implementations, which are as far as I know MRI, YARV, JRuby, IronRuby, Rubinius, MacRuby, MRuby, MagLev, and TruffleRuby.

Equivalent of String#setbyte and String#getbyte in ruby 1.8

Trying to get the aerospike ruby client to work under 1.8
What is the equivalent of these calls in ruby 1.8 ?
https://github.com/aerospike/aerospike-client-ruby/blob/master/lib/aerospike/utils/buffer.rb#L65
https://github.com/aerospike/aerospike-client-ruby/blob/master/lib/aerospike/utils/buffer.rb#L95
IIRC, Ruby 1.8 strings are, for all intents and purposes, what 1.9 would treat as ASCII-8BIT. As such, String#[] and String#[]= are the way to proceed as already suggested in the comments. (The same functions in 1.9 will target a potentially multibyte character at a certain offset, rather than a byte.)
For a more complete discussion on Ruby M17N and how strings changed in Ruby 1.9, see:
http://yokolet.blogspot.com/2009/07/design-and-implementation-of-ruby-m17n.html
http://yehudakatz.com/2010/05/05/ruby-1-9-encodings-a-primer-and-the-solution-for-rails/
Rather than rely on how a particular version of Ruby processes bytes/chars/strings, instead use the pack and unpack methods. They are always available and behave consistently.
For your use, unpack the data into an array, then you can use normal Array slicing to change the bytes in question, then pack everything back into the byte-stream.

Do you know an alternative ctags generator for Ruby

Exumerant Ctags does not work well with Ruby, you can see there are many hacks in the ruby.c code and basically it fails recognizing many cases. One of the most important is this bit:
class SomeModule::SomeClass
end
Ctags generates:
SomeModule someclass.rb /^class SomeModule::SomeClass$/;" c
which is wrong. The correct and expected entry is:
SomeClass someclass.rb /^class SomeModule::SomeClass$/;" c
This is very limiting. There are some patches for ctags available which does not work, e.g. https://github.com/xtao/overlay/blob/master/dev-util/ctags/files/ctags-5.5.4-ruby-classes.patch but looking on the ctags ruby codebase, this really needs complete rewrite.
So I have been playing with other option which is https://github.com/rdoc/rdoc-tags which works nicer, but it is slow. I mean really SLOW. Generating tags on my project is 2 seconds with ctags but one hour with this tool. Really.
I found one old project that was parsing Ruby on it's own and generating tags, but it was only for Ruby 1.8. It was slower than ctags, but not that bad.
So I am searching for some alternatives. Do you know about any other working ruby ctags generators which give you proper output and are fast?
Thanks!
Edit: I have found very nice project that works with Ruby 1.9+ and is accurate and fast. I recommend it:
https://github.com/tmm1/ripper-tags
Ripper-tags effort does solve everything described here. It is based on official Ruby parser which is also quite fast. https://github.com/tmm1/ripper-tags
gem install ripper-tags
cd your_project/
ripper-tags -R
It does also support Emacs as well.
Exuberant ctags out of the box doesn’t do a number of useful things:
It doesn’t deal with:
module A::B
It doesn’t tag (at least some of) the “operator” methods like ‘==’
It doesn’t support qualified tags, —type=+
It doesn’t output tags for constants or attributes.
Patch available, but it is only for version 5.5 and does not work anymore.
Other projects:
https://github.com/tmm1/ripper-tags (best option for Ruby 1.9+)
https://rubygems.org/gems/rdoc-tags (very slow but works with 1.8)
Source
Add following to your ~/.ctags
--regex-ruby=/(^|;)[ \t]*(class|module)[ \t]+([A-Z][[:alnum:]_]+(::[A-Z][[:alnum:]_]+)+)/\3/c,class,constant/
So you can:
deal with: module A::B
See more here: https://github.com/bltavares/dot-files/blob/master/ctags
A patch is available as of 2013-02
https://github.com/fishman/ctags (ctags patch for Ruby, including rspec)
the rspec tag generator will not properly recognize describe blocks that start with semicolor (:some-method), but other than that, it's great.
There is also https://github.com/eapache/starscope
It doesn't support the extended tag format (yet) but it does other things such as exporting cscope databases.

Do all Ruby interpreters follow the same Ruby syntax?

Do all Ruby interpreters follow the same Ruby syntax defined in www.ruby-lang.org?
MRI
YARV
Rubinius
JRuby
IronRuby
Cause it is the interpreter that defines the Ruby language. Does that mean one interpreter could add a feature/syntatic sugar that other interpreters haven't?
If that is the case, do all interpreters have their own API documentation?
Cause I'm using: http://ruby-doc.org/ruby-1.9/index.html.
Which interpreters are implementing that one?
Could someone shed a light on this topic.
Thanks!
Do all Ruby interpreters follow the same Ruby syntax defined in www.ruby-lang.org?
Yes, they all use the same syntax. In fact, they actually all use the same parser, or at least a parser that was automatically generated from the same source file.
Cause I'm using: http://ruby-doc.org/ruby-1.9/index.html.
Which interpreters are implementing that one?
At the moment, the only production-ready Ruby execution engine that implements Ruby 1.9 fully is YARV.
JRuby itself is production-ready, and it implements both Ruby 1.8.7 and Ruby 1.9.2, but the Ruby 1.9.2 implementation is not yet complete. IronRuby and Rubinius are also working on implementations of Ruby 1.9.2. MacRuby has a fairly complete Ruby 1.9 implementation, but it is still far from a 1.0 release. MRI doesn't implement Ruby 1.9 and probably never will.
But I don't understand why you are so concerned about the syntax. Syntax differences are trivial to spot: if there were a difference in the syntax, the engine would simply refuse to parse your file and you would know immediately that there is something wrong. Differences in semantics on the other hand are much more dangerous.
Which bit of "syntactic sugar" are you referring to?
Keep in mind that ruby has a very small set of keywords. A lot of stuff that seems to be a keyword at first is actually implemented by Kernel (eg require, puts, and raise).
http://apidock.com/ruby/Kernel

Where can I find an actively developed lint tool for Ruby?

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.

Resources