Emacs ruby mode if expressions indentation - ruby

Emacs 24 ruby-mode insists on indenting if expressions the following way:
before1 = if params[:before]
Time.zone.at(params[:before].to_i)
end
Which i find just plain wrong. The expected behavior should be:
before1 = if params[:before]
Time.zone.at(params[:before].to_i)
end
That is - the if block should be indented by exactly one level relative to the line in which the if expression starts. Is there any way to achieve this?

If your Emacs is recent enough (24.4+) and you're using the SMIE indentation engine (ruby-use-smie is non-nil), you can use ruby-align-to-stmt-keywords:
(add-to-list 'ruby-align-to-stmt-keywords 'if)

I guess you actually meant to say that Emacs aligns the if with the end, which is actually pretty idiomatic in Ruby (and the style enforced by tools like RuboCop). The second indentation style is popular for method class with blocks, but not for expressions like if/unless/case.
Currently there is now way to change this behaviour. There are plans to introduce a more flexible indentation scheme in ruby-mode in the future, but that's not going to happen in the next Emacs release.
At any rate - it's not a bug, it's a feature :-)

Related

Sublime text 3 ugly syntax highlighting

I'm learning Ruby and I'm using Sublime Text 3 but I find the syntax highlighting really strange.
For example :
Ugly syntax
Even after setting the syntax to ruby.
Ruby syntax set
I'd like to know if this is normal, or if I need to change something on the users
settings or something like that.
The syntax file for Ruby (Ruby.sublime-syntax) contains a list of unresolved issues. Among them is:
text:
"p << end
print me!
end"
symptoms:
not recognized as a heredoc
solution:
there is no way to distinguish perfectly between the << operator and the start
of a heredoc. Currently, we require assignment to recognize a heredoc. More
refinement is possible.
• Heredocs with indented terminators (<<-) are always distinguishable, however.
• Nested heredocs are not really supportable at present
So yeah, it's normal.
You could visit https://packagecontrol.io/ and use something like Railscast Colour Scheme
The basic syntax highlighting that comes w/ sublime is pretty sparse - these packages usually do a better job. Also this is just one example. There's plenty of themes and color schemes.
To install package control ctrl+ and past in the snippet according to your version of sublime from this page https://packagecontrol.io/installation#st3

Commented string to fix emacs ruby mode highlighting

Sometimes, parsing done by text editors for syntax highlighting is not accurate. It often happens that introducing a heredoc in ruby-mode messes up syntax highlighting on emacs as in this question. I am having problem with such case:
<<_
some here doc content
...
last line of the intended heredoc
_
this_ruby_code_line_and_any_line_after_it_is_highlightened_as_part_of_heredoc
I do not expect a fix on emacs ruby-mode for this, but is there some kind of a commented string that I can generally put between the heredoc and the following Ruby code in order to reset the highlighting problem? When I have problems not with heredoc but with funky string literals (especially those including quotes), sometimes, putting a commented string like
#"'`
at the end of the line fixes the problem. Is there such thing to fix the problem for heredoc, and further, is there a string that can be used more generally?
Works fine for me in an Emacs trunk build.
Try a more recent Emacs version (I'm quite certain that this works in the upcoming 24.3 version, but maybe in the current release, too) and/or make sure that you are using ruby-mode bundled with Emacs, not installed through ELPA, etc:
ELISP> (require 'which-func)
which-func
ELISP> (find-library-name "ruby-mode")
"/home/gutov/emacs-bzr/trunk/lisp/progmodes/ruby-mode.el"

Emacs ruby-mode indenting customization for case..when and assignment from an if..else?

In Emacs, using ruby-mode, I can't find a way to stop this happening:
foo = if something?
42
else
7
end
When our in-house conventions are:
foo = if something?
42
else
7
end
(Same goes for begin..end and case..when).
Also, while it's less of a nuisance, our convention for case..when is to indent each when.
case whatever
when foo
"a"
when bar
"b"
else
"c"
end
I know people generally say you should align the when with the case, but it's not the convention of our company, so does anybody know how to customize this too? I can find very little customization for ruby-mode. The only thing I've really been able to customize is the indentation inside parentheses.
In Emacs 24.4 and newer, you can set ruby-align-to-stmt-keywords to '(if begin case), or simply to t, to resolve the first part of your question.
It won't change the indentation offset of when, though. That would have to be a different option.
There is no way to customize this. ruby-mode is pretty barebone as far as indentation customizations are concerned and Matz (its original author) is totally adamant in supporting the standard style for case indentation.

Vim and Ruby - matching "do"s and "end"s?

I'm sure we're all familiar with the "unexpected kEnd" problem. They are always (to me) a lot of trouble to track down, because Vim doesn't match "do"s and "end"s. (And, obviously, other elements that end with "end", like "if")
Is there a way to configure Vim to show these matches to help make debugging easier?
If you are using a recent vim (I'm using 7.4), the built-in matchit macro works well with ruby code.
Simply enable it by adding the following to your .vimrc
runtime macros/matchit.vim
Hit % to match do/end combos and many others in ruby files.
I use this macro and then add this to my vimrc to enable it:
" % to bounce from do to end etc.
runtime! macros/matchit.vim
When I want to find the matching end for a do, I cursor over the do and hit %.
"endwise" is a pretty nice vim extension that adds them automatically, which I found greatly reduces the amount of missing ends. etc:
http://www.vim.org/scripts/script.php?script_id=2386
I use this matchit clone, that can be installed easily with vundle.

Ruby Equivalent of C++ Const?

I'm learning Ruby in my spare time, and I have a question about language constructs for constants. Does Ruby have an equivalent of the C++ const keyword to keep variables from being modified? Here's some example code:
first_line = f.gets().chomp()
column_count = first_line.split( %r{\s+} ).size()
print column_count, "\n"
I'd like to declare column_count to be const, because I use it below in my program and I really don't want to modify it by mistake. Does Ruby provide a language construct for doing this, or should I just suck it up and realize that my variables are always mutable?
Response to comments:
'The most likely cause of "accidental" overwriting of variables is, I'd guess, long blocks of code.' I agree with the spirit of your point, but disagree with the letter. Your point about avoiding long blocks of code and unnecessary state is a good one, but for constants can also be useful in describing the design of code inside of the implementation. A large part of the value of const in my code comes from annotating which variables I SHOULD change and which I shouldn't, so that I'm not tempted to change them if I come back to my code next year. This is the same sentiment that suggests that code that uses short comments because of good variable names and clear indentation is better than awkwardly written code explained by detailed comments.
Another option appears to be Ruby's #freeze method, which I like the look of as well. Thanks for the responses everyone.
Ruby variables in general are, well, variable.
Beyond Jeremy's answer, while entirely accurate, doesn't lead you to a Ruby style that's very "mainstream" or idiomatically sound and I wouldn't recommend it for adoption. Ruby doesn't work like C++ and generally isn't very appropriate for things that C++ is best used for. Operating systems, word processors, that kind of thing.
The most likely cause of "accidental" overwriting of variables is, I'd guess, long blocks of code. After all, if you change the value of a variable in a five-line method, it's going to be fairly apparent! If you're habitually writing blocks of code longer than, say, 10 lines, then those chunks are probably doing too many things and I strongly advise that you make efforts to break them up (increase cohesion). Localise variables as much as possible to minimise the chance of unexpected side-effects (reduce coupling).
By convention, constants in ruby are generally written in all caps such as COLUMN_COUNT. But as it was pointed out, all variables that start with a capital letter are Constants.
Variables that start with a capital letter are constants in Ruby. So you could change your code to this:
first_line = f.gets().chomp()
Column_count = first_line.split( %r{\s+} ).size()
print Column_count, "\n"
Now you'll get a warning if you try to modify Column_count.

Resources