Can someone please explain what (:+) is in Ruby? I have tried googling it & looking a reference guides and cant find anything. Thanks, sorry Im pretty new to Ruby & programming.
A colon : before a sequence of characters* is a Symbol literal. This applies to :+, which is a Symbol with content "+".
A symbol can be used to reference a method with the same name in some contexts, and in a couple of places your example :+ can be a reference to the + operator, which is really just a method with the same name. Ruby supports syntax to call it when it sees a plain + in an expression, or in some core methods it will convert :+
As an example you can use :+ as shorthand to create a sum of an Array of integers:
[1,2,3,4].inject( :+ )
=> 10
This works because Ruby has special-cased that specific use of operators in Array#inject (actually defined in Enumberable#inject, and Array gets it from that module).
A more general use-case for a symbol like this is the send method:
2.send( :+, 2 )
=> 4
Although 2.send( "+", 2 ) works just fine too. It might seem odd when used like this instead of just 2 + 2, but it can be handy if you want to make a more dynamic choice of operator.
* The rules for the syntax allowed or not allowed in a Symbol literal are a little arcane. They enable you to write shorter literals where possible, but Ruby has to avoid some ambiguous syntax such as a Symbol with a . or whitespace in the middle. This is allowed, just you have to add quotes if you generate such a Symbol e.g. :"this.that"
Ruby will tell you
:+.class
# Symbol
(:+) is the symbol in parentheses.
Related
I don't get it that [] is an operator in ruby. I was wondering that if [] is an operator then what are these parenthesis {} & (). Are these also operators?
What I know is that these symbols are used by the language parser for interpreting/compiling code.
It depends if you're talking about array literals or those brackets used for getting or assigning values from/to arrays or hashes.
As a literal, [] is just an array literal, shorthand for writing Array.new. You also asked about {}, which is a hash literal, i.e. shorthand for writing Hash.new. Parentheses are not literals (or 'operators' for that matter) – they're used to group things.
As an 'operator' for getting or assigning values, as others have pointed out in the comments, [] isn't special or conceptually different from other 'operators'.
In the same way 2 + 3 is sugar for writing 2.+(3), writing array[0] is sugar for writing array.[](0).
The reason this works is that arrays have a method that's literally called []. You can find it by getting all the methods on an array:
[].methods
# => long array including :[] (and also :[]=, by the way, for assignments)
Note that the brackets in [].methods are an array literal, not an 'operator'.
I haven't looked at the implementation of any Ruby interpreters, but my guess is they see something like array[0] and convert it to array.[](0) (or at least they treat it as such). That's why this kind of sugar syntax works and looks like 'operators' even though it's all methods under the hood.
In Ruby, I am taking an incoming from a file representing an XML document, but containing some Ruby interpolation code. Here is an example:
<ns1: xmlns:ns1="http://example.com" attr="#{Time.now}">
Now, when I want to evaluate the string to resolve the Ruby references, I have tried the following:
xs = '<ns1: xmlns:ns1="http://example.com" attr="#{Time.now}">'
eval("'" + xs + "'") #=> "<ns1: xmlns:ns1=\"http://example.com\" attr=\"\#{Time.now}\">"
eval %Q{"'" + #{xs} + "'"} # SyntaxError: (eval):1: syntax error, unexpected '<'
eval('"' + %Q{#{xs}} + '"') # SyntaxError: (eval):1: syntax error, unexpected tIDENTIFIER, expecting end-of-input
I don't know how else to do this. How can I evaluate the string with interpolation so that I get the following:
<ns1: xmlns:ns1="http://example.com" attr="2017-06-22 11:58:39 +0200">
As suggested by Jörg, you'll have much better experience if you use one of the templating languages. I suggested ERB, because it's built-in.
xs = '<ns1: xmlns:ns1="http://example.com" attr="<%= Time.now %>">'
require 'erb'
ERB.new(xs).result(binding)
# => "<ns1: xmlns:ns1=\"http://example.com\" attr=\"2017-06-23 09:11:56 +0300\">"
You are not looking for string interpolation. You are looking for a templating language.
String interpolation is for interpolating Ruby code in a string (or symbol) literal. You don't have a literal, you have a reference to an object. String interpolation doesn't work, it doesn't even apply to this situation.
What you have here instead is a templating language whose syntax happens to be identical to Ruby's string interpolation syntax. You need an implementation for that language; unfortunately, AFAIK there isn't one, so you will have to write your own. Writing a very simple, not very robust templating engine used to be a popular exercise in Ruby a couple of years ago, so I happen to know that it only takes a couple of minutes (and lines). (Making it robust, safe, and secure in the face of untrusted arbitrary input is a whole different matter, though.)
If you could change the input format to an existing templating language, that would be easiest. One well-known templating language in the Ruby world is ERb, which actually has an implementation in the standard library. There's also Tenjin, Liquid, Ruty, Mustache, to name but a few.
Is it possible to split a symbol without first converting it to a string? For example, I've tried
:split_this.split("_")
and it only returns an error. I've looked through the Symbol class reference, but all the example use to_s to convert it to a string.
I know I can convert it to a string, split it, and convert the two substrings to symbols, but that just seems a bit cumbersome. Is there a more elegant way to do this?
Since Ruby 1.9 some string's features are added to the Symbol class but not this much.The best you can do, I think is:
:symbol_with_underscores.to_s.split('_').map(&:to_sym)
You could turn this into a Symbol method:
class Symbol
def split(separator)
to_s.split(separator).map(&:to_sym)
end
end
:symbol_with_underscores.split('_')
# => [:symbol, :with, :underscores]
Think about symbols as numbers. Because symbols are internally stored as int numbers. Therefore they don't have string related methods.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Understanding Symbols In Ruby
What is the colon operator in Ruby?
I really feel naive asking this, but I'm going to go ahead and ask :
What is the importance of : in ruby ?
I have seen it being used in a number of places like params[:id] or like x < :length.
A colon denotes a "symbol". A symbol is like a string, but it is immutable (you can't change its contents). Behind the scenes, it also takes up less memory, since a symbol only needs to exist once in memory (i.e., two strings called "length" will exist twice in memory, but two symbols called :length will point to the same object).
:length means it is a Symbol
Symbols are Strings, just with an important difference, Symbols are immutable.
RubyDoc: Symbol objects represent names and some strings inside the Ruby interpreter. They are generated using the :name and :"string" literals syntax, and by the various to_sym methods.
Here are some good places to learn more about symbols
The Ruby_Newbie Guide to Symbols
Understanding Ruby Symbols
The Difference Between Ruby Symbols and Strings
It is syntax indication of type for interpreter.
0-9 numeric*
: symbol
"" string
[] array
{} hash
Patterns more complicated in reality.
I am learning Ruby. My background is C++/Java/C#. Overall, I like the language, but I am a little confused about why there are so many different ways to accomplish the same thing, each with their own slightly different semantics.
Take string creation, for example. I can use '', "", q%, Q%, or just % to create strings. Some forms support interpolation. Other forms allow me to specify the string delimiters.
Why are there five ways to create string literals? Why would I ever use non-interpolated strings? What advantage does the % syntax have over quoted literals?
I know there must be value in the redundency in Ruby, but my untrained eyes are not clearly seeing it. Please enlighten me.
Why would I ever use non-interpolated strings?
When you don't want the interpolation, of course. For example, perhaps you're outputting some documentation about string interpolation:
'Use #{x} to interpolate the value of x.'
=> "Use #{x} to interpolate the value of x."
What advantage does the % syntax have over quoted literals?
It lets you write strings more naturally, without the quotes, or when you don't want to escape a lot of things, analogous to C#'s string-literal prefix #.
%{The % syntax make strings look more "natural".}
=> "The % syntax makes strings look more \"natural\"."
%{<basket size="50">}
=> "<basket size=\"50\">"
There are many other %-notations:
%w{apple banana #{1}cucumber} # [w]hitespace-separated array, no interpolation
=> ["apple", "banana", "\#{1}cucumber"]
%W{apple banana #{1}cucumber} # [W]hitespace-separated array with interpolation
=> ["apple", "banana", "1cucumber"]
# [r]egular expression (finds all unary primes)
%r{^1?$|^(11+?)\1+$}
=> /^1?$|^(11+?)\1+$/
(1..30).to_a.select{ |i| ("1" * i) !~ %r{^1?$|^(11+?)\1+$} }
=> [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
%x{ruby --version} # [s]hell command
=> "ruby 1.9.1p129 (2009-05-12 revision 23412) [x86_64-linux]\n"
There's also %s (for symbols) and some others.
Why are there five ways to create string literals?
This isn't terribly unusual. Consider C#, for example, which has several different ways to generate strings: new String(); ""; #""; StringBuilder.ToString(), et cetera.
I'm not a Ruby expert, but had you ever heard the term "syntactic sugar" ? Basically some programing languages offer different syntax to accomplish the same task. Some people could find one way easier than others due to his previous programing/syntax experience.
The original question is why there are so many slightly different ways of doing things in Ruby.
Sometimes the different things are sensible: quoting is a good case where different behaviour requires different syntax - non/interpolating, alternate quoting characters, etc. - and historical accidence causes synonyms like %x() vs ``, much as in Perl.
The synonym issue - [].size [].length [].count - feels like an attempt to be helpful in a world where the language is too random for IDEs to be able to help: monkey-patching and the weird combination of strict but dynamic typing together make runtime errors an inevitable and frustrating part of the coding, so folks try to reduce the issue by supplying synonyms. Unfortunately, they end up confusing programmers who're accustomed to different methods doing different things.
The 'so similar but not quite' issue, for example ...
$ ruby -le 'e=[]; e << (*[:A, :B])'
-e:1: syntax error, unexpected ')', expecting :: or '[' or '.'
$ ruby -le 'e=[]; e << *[:A, :B]'
-e:1: syntax error, unexpected *
$ ruby -le 'e=[]; e.push(*[:A, :B])'
$
... can only really be viewed as a flaw. Every language has them, but they're usually more arcane than this.
And then there's the plain arbitrary 'use fail instead of raise unless you're just rethrowing an exception' nonsense in the Rubocop coding standards.
There are some nice bits in Ruby, but really - I'd far rather be coding in something better-founded.
In most situations, you'll end up using normal string delimiters. The main difference between single and double quotes is that double quotes allow you to interpolate variables.
puts 'this is a string'
# => this is a string
puts "this is a string"
# => this is a string
v = "string"
puts 'this is a #{v}'
# => this is a #{v}
puts "this is a #{v}"
# => this is a string
%q and %Q are useful when you can't use quotes because they are part of the internal string.
For example, you might end up writing
html = %Q{this is a <img src="#{img_path}" class="style" /> image tag}
In this case, you can't use double quotes as delimiters unless you want to escape internal attribute delimiters. Also, you can't use single quote because the img_path variable won't be interpolated.
A lot of ruby's syntax is derived from perl's, like using q to quote a few words into a string. That probably is the main reason for such a big variety.
One more reason is a minor performance boost for non-interpolated strings. Using '' vs "" means that Ruby doesn't have to consider what's inside the string at all. So you'll see people using single quotes for array keys or symbols because they're faster. For what it's worth I'll include a little benchmark.
require 'benchmark'
Benchmark.bmbm(10) do |x|
x.report("single-quote") do
for z in 0..1000000
zf = 'hello'
end
end
x.report("double-quote") do
for z in 0..1000000
zf = "hello"
end
end
x.report("symbol") do
for z in 0..1000000
zf = :hello
end
end
end
yields:
Rehearsal ------------------------------------------------
single-quote 0.610000 0.000000 0.610000 ( 0.620387)
double-quote 0.630000 0.000000 0.630000 ( 0.627018)
symbol 0.270000 0.000000 0.270000 ( 0.309873)
--------------------------------------- total: 1.580000sec
You would use non-interpolated strings if your string contains a lot of special characters (like backslashes, #{} etc.) and you don't want to escape all of them.
You'd use different delimiters if your string contains a lot of quotes that you'd otherwise have to escape.
You'd use heredocs if your strings has a lot of lines which would make normal string syntax look unwieldy.
Ruby borrows constructs and ideas from lots of languages. The two most apparent influences are Smalltalk and Perl.
Depending on your comfort with Smalltalk or Perl you may well choose different constructs to do the same thing.
Along the lines of John's answer:
In quick hacks, I often end up running a perl or sed one-liner with grep syntax from within my ruby script. Being able to use %[ ] type syntax means that I can simply copy-paste my regexp from the terminal