There are two ways of enabling all strings in a file to be implicitly frozen1.
# frozen-string-literal: true
# frozen_string_literal: true
Is there a difference between these two syntaxes?
Thanks!
The answer you link to never uses the magic comment # frozen-string-literal: true only # frozen_string_literal: true. The difference is that only the latter will work.
The other way to enable frozen string literals is to run the application with the --enable=frozen-string-literal flag.
Related
In ruby one can freeze all constant strings in a file via two different magic comments at the beginning of a file:
# frozen_string_literal: true
and
# -*- immutable: string -*-
I have no idea what the differences are.
Are there any?
The 1st syntax is the magic comment for Ruby 2.3+ versions to freeze string literals, otherwise you have to use the String method like this:
'hello world!'.freeze
The 2nd syntax is not implemented in Ruby, however it is the way that variables are specified for files in the Emacs text editor.
For example, the following comment in Emacs would declare that the file is a Ruby file and needs Ruby syntax highlighting, and that the variable immutable is set to the value string.
# -*- mode: ruby; immutable: string -*-
After searching around, it looks like that does nothing and is not used by any Ruby syntax highlighting mode.
So you do not need the 2nd syntax.
Digging for anything on the 2nd version, it looks like they had the same intention but the 2nd magic comment syntax does not to appear to have been adopted as of Ruby 2.1.0.
See https://github.com/ruby/ruby/pull/487
The first version # frozen_string_literal: true was adopted in Ruby 2.3.0
I tried the latter version in a few versions of ruby but didn't work. I would guess it should not be used or trusted to work in any version of >= 2.3 but probably no versions support it. In fact, I was not able to find any reference to that version in the open source code on github searching that syntax
https://github.com/ruby/ruby/search?q=immutable%3A+string&unscoped_q=immutable%3A+string
Rubocop changes #!/usr/bin/ruby to
# !/usr/bin/ruby
adds a space after the hash when I use rubocop -a, how can I avoid this
You'll have to disable the LeadingCommentSpace cop. It ensures that there is a space between # and the text that follows it. Puts something like this in your .rubocop.yml:
LeadingCommentSpace:
enabled: false
What you've stumbled upon is a bug, that I'll fix in the next RuboCop release (I'm its author). Obviously #! should be treated specially.
I know I could use eval to get the string back like below:
"".inspect == "\"\"" # true
eval("\"\"") == "" # true
But besides eval, is there an another way to do it?
In your case, "" is an empty string. "\"\"" is something completely else: A string that, when it is fed to something, yields your "" empty string. And that something, in this case, is Ruby interpreter. In other words, "\"\"" dump is specifically intended to be eveluated by Ruby interpreter, wheter in eval, instance_eval, class_eval, or ruby command line, or irb, or what...
Even if there is another way to do it, that way will only end up emulating Ruby interpreter. So I dare to say, no, it does not make too much sense to do it another way.
But besides eval, is there an another way to do it?
Yes possible,look below using YAML :
require 'yaml'
YAML.load("\"\"") # => ""
YAML.load("\"\"") == "" # => true
I notice an surprising behavior of the fnmatch function of Ruby:
File.fnmatch('**.rb', 'main.rb') #=> true
File.fnmatch('**.rb', './main.rb') #=> false
As far as being explained in the the Ruby reference, ** will:
Matches directories recursively or files expansively.
So why doesn't it expands and matches ./main.rb?
This behavior is actually documented, but it's easy to miss. Buried in the examples it says:
wildcard doesn't match leading period by default.
To enable this behavior, you need to specify the File::FNM_DOTMATCH flag:
File.fnmatch('**.rb', './main.rb', File::FNM_DOTMATCH)
=> true
Ruby 1.9.3 defaults to using Psych for YAML. While the ruby-doc documentation for it is completely lacking, I was able to find one external piece of documentation that hinted that the indentation option is supported. This was borne out in testing:
irb(main):001:0> RUBY_VERSION
#=> "1.9.3"
irb(main):002:0> require 'yaml'
#=> true
irb(main):003:0> [[[1]]].to_yaml
#=> "---\n- - - 1\n"
irb(main):009:0> [[[1]]].to_yaml indentation:9
#=> "---\n- - - 1\n"
There are presumably more options supported. Specifically, I want to know how to change the line wrap width or disable it altogether.
What are the options available?
Deep in the guts of ruby-1.9.3-p125/ext/psych/emitter.c I found three options:
indentation - The level must be less than 10 and greater than 1.
line_width - Set the preferred line width.
canonical - Set the output style to canonical, or not (true/false).
And they work!
When you want to disable line wrap, use this option:
line_width: -1