What's the Point of the prefix ? operator in Ruby 1.9
It's mainly for backwards compatibility. In versions prior to 1.9, ?
evaluated to a Fixnum
corresponding to the ASCII value of the character in question. Indexing into a String
also returned a Fixnum
.
So, if you wanted to check, for example, if the third character of a string was the letter 'a' you would do
s[2] == ?a
In Ruby 1.9, strings are no longer treated as an array of fixnums but as an iterator of characters (single-character strings, actually). As a result, the above code would no longer work: s[2]
would be a string, ?a
would be a number, and those two would never be equal.
Therefore, ?
was also changed to evaluate to a single-character string, so that the above code continues to work.
What's the Point of the prefix ? operator in Ruby 1.9
It's mainly for backwards compatibility. In versions prior to 1.9, ?
evaluated to a Fixnum
corresponding to the ASCII value of the character in question. Indexing into a String
also returned a Fixnum
.
So, if you wanted to check, for example, if the third character of a string was the letter 'a' you would do
s[2] == ?a
In Ruby 1.9, strings are no longer treated as an array of fixnums but as an iterator of characters (single-character strings, actually). As a result, the above code would no longer work: s[2]
would be a string, ?a
would be a number, and those two would never be equal.
Therefore, ?
was also changed to evaluate to a single-character string, so that the above code continues to work.
Ruby: Curious usage of ? operator in comparing strings for equality
This is old syntax for one char strings.
?-
means '-'
EDIT: turns out, I couldn't be more wrong. See @Jörg's comment below.
ruby 1.9.x, weird parsing, what's going on?
Ruby 1.8.7 also supports unary +
, and gives the same error for +'='
.
I would assume something changed in the parsing logic, and a +'='
is parsed as an unary plus in your expression. I wouldn't consider that a bug.
What does the (unary) * operator do in this Ruby code?
The *
is the splat operator.
It expands an Array
into a list of arguments, in this case a list of arguments to the Hash.[]
method. (To be more precise, it expands any object that responds to to_ary
/to_a
, or to_a
in Ruby 1.9.)
To illustrate, the following two statements are equal:
method arg1, arg2, arg3
method *[arg1, arg2, arg3]
It can also be used in a different context, to catch all remaining method arguments in a method definition. In that case, it does not expand, but combine:
def method2(*args) # args will hold Array of all arguments
end
Some more detailed information here.
How to use ampersand prefix with other arguments
Try
raw = File.open(fname).read
Edit: The problem with this is that it doesn't close the file, as OP stated.
However this does work with ruby 1.9.3p448:
raw = File.open(fname, &:read)
This is just to demonstrate the use of the &/symbol representation of a block in ruby. As sawa points out, in actual practice one would ordinarily do:
raw = File.read(fname)
ruby double question mark
Ruby 1.8 has a ?-prefix syntax that turns a character into its ASCII code value. For example, ?a
is the ASCII value for the letter a
(or 97). The double question mark you see is really just the number 63
(or the ASCII value for ?
).
?a # => 97
?b # => 98
?c # => 99
?\n # => 10
?? # => 63
To convert back, you can use the chr
method:
97.chr # => "a"
10.chr # => "\n"
63.chr # => "?"
??.chr # => "?"
In Ruby 1.9, the ?a
syntax returns the character itself (as does the square bracket syntax on strings):
?? # => "?"
"What?"[-1] # => "?"
Space before star breaks syntax in ruby multiplication statement
*
is used for both an operator (42 * 42
) and argument unpacking (myfun *[42, 42]
).
When you do:
m.x *m.x
2/m.x *m.x
Ruby interprets this as argument unpacking, rather than the *
operator (ie. multiplication).
In case you're not familiar with it, argument unpacking (sometimes also called "splat", or "splats") means that you can have a function like this:
def myfun arg1, arg2; end
And call it like this:
myfun(*['Hello', 'World'])
arg1
is set to Hello
, and arg2
is set to World
.
I believe the rules are to determine which to use is:
- Space before but not after a
*
-> Argument unpacking - Start of function parenthesis -> Argument unpacking
- Everything else -> Multiplication (or rather, the
*
operator, since Ruby does operator overloading).
Good guidelines are:
- Use the "optional" function parenthesis when you intend argument unpacking;
- use spaces before and after
*
when you intend the*
operator (multiplication).
Ruby will actually warn you about this when you run ruby -v
:
test.rb|11 warning| `*' interpreted as argument prefix
test.rb|12 warning| `*' interpreted as argument prefix
Related Topics
How to Format Irb Command Prompt
The Compiler Failed to Generate an Executable File. (Runtimeerror)
Why Can't I Access a Local Variable Inside a Method in Ruby
How to Use Rspec to Mock Stdin/Stdout to Test Console Reads & Writes
Using Rbenv Doesn't Work with Sudo
Converting from Xml Name-Values into Simple Hash
Order Products by Association Count
Ruby - Digest::Digest Is Deprecated; Use Digest
Rails 3 Install Error: "Invalid Value for @Cert_Chain"
How to Get a Particular Line from a File
Rails Select Drop Down for States
How to Click First Link in List of Items After Upgrading to Capybara 2.0