That being said, I can't help but shake my head at the section about "multiple assignment of conditionals:
"You can now assign multiple variables within a conditional...You probably shouldn’t do that though."
Am I alone and thinking that it's a little bit hypocritical to specifically add functionality to your language if you don't want people to use it? Or is this just a joke that's gone over my head?
It's just a change to make the language more consistent. `a, b = something` already worked as an expression in most places, so it makes sense that it should be allowed on `if` conditions too. Before 2.4:
> if (a, b = nil) then :foo else :bar end
SyntaxError: (eval):2: multiple assignment in conditional
So instead of having that special syntax error, and probably needing a justification for it, Ruby 2.4 makes `a, b = something` a valid expression there and removes an edge case.That you probably shouldn't use multiple assignment on an `if` condition is a separate issue. It's just a preference, and it follows the same logic of avoiding assignments on conditional expressions in general.
irb(main): a, b == 3
SyntaxError: syntax error, unexpected ==, expecting '='
Should it still be avoided? :) while x, y = foo.pop
..
end
which without the mass assignment will require duplication of the assignment line. branch1 =
if (foo, bar = %w[foo bar])
'truthy'
else
'falsey'
end
branch2 =
if (foo, bar = nil)
'truthy'
else
'falsey'
end
branch1 # => "truthy"
branch2 # => "falsey"
What about branch3 =
if (foo, bar = ['foo', nil])
'truthy'
else
'falsey'
end
? foo, bar = ['foo', nil]
evaluates to ['foo', nil]
which is truthy.If the code was:
if (foo, bar = [nil, nil])
'truthy'
else
'falsey'
end
It'd still be truthy even if no variables were "set" (they were actually set, explicitly to nil, but you get the idea) because [nil, nil] is truthy. It doesn't have anything to do with the values of the variables after the assignment, just what's on the right hand side. irb(main): a, b = nil
=> [nil]
In Ruby, non-empty arrays always evaluate to truthy. (The array above has one element, nil.) Hence, multiple assignment inside a conditional would have been meaningless. For this reason, Ruby threw a parse error.As of Ruby 1.9, multiple assignment in a conditional now returns whatever the right-hand side of the assignment operator evaluates to. So, it makes sense to re-allow multiple assignment inside conditionals and remove the parse error.
Here are some examples illustrating the return value of multiple assignment. The first two are truthy while the third is falsey:
irb(main): a, b = 8, 7
=> [8, 7]
irb(main): a, b = 8
=> 8
(a = 8, b = nil)
irb(main): a, b = nil
=> nil
(a = nil, b = nil)
- The above based on user 'bug hit' who attributes Yusuke Endoh, from https://bugs.ruby-lang.org/issues/10617Second, I would not say Ruby is not a language for the multi-core world. There are tens of thousands Ruby production environments over the world that make excellent use of multi-core machines. They run Ruby on problems that are embarassingly parallel such as web applications using process managing application servers such as Phusion Passenger or Unicorn. This is the way many modern web application platforms parallelize, including Node.JS and Python.
Third lack of paralellization is not a language feature. Both JRuby and Rubininus support threads without a GIL. Projects like Celluloid and Concurrent-Ruby make use of this.
2.Passenger and Unicorn are multi-process, which due to developers can make use of nearly nothing in Ruby, and that's why gems like https://github.com/grosser/parallel come out.
3. The language implementation detail matters a lot. Too many gems are not thread-safe. JRuby is an option, but not that good, as there're too many other options under JVM platform. Rubininus is awesome, I wish it comes out earlier.
MRI isn't the implementation for the multi-core world, but MRI isn't the only Ruby implementation; on language features, JRuby, particularly, isn't particularly far behind (the current version runs Ruby 2.3 code; I wouldn't expect 2.4 support to be that far behind), and fully supports thread-based parallelism.
Not really; it depends on the audience. The Ruby audience is still mainly Rails development, whose paradigm is multi-process.
Why? This doesn't seem necessary, but, more importantly, would be inconsistent with #inject's behaviour (if enforced).
----
http://ruby-doc.org/core-2.3.1/Enumerable.html#method-i-inje...:
If you do not explicitly specify an initial value for memo, then the first element of collection is used as the initial value of memo
Forcing the use of the additive identity every time, rather than starting with the first element of the collection, is a good way of setting people up to get the correct behaviour on empty collections, even if they don't test for that case.
so probably no, this won't be the last release before ruby 3.
`num.to_s.split(//).map(&:to_i)` => `num.digits`
num.to_s.chars.map &:hex
So digits only saves 14 characters (22 if reverse is really necessary). But usually we would actually be doing something with the digits instead of just getting them, so the method may save even less.
For example, for finding digit sums, the new digits and sum methods give us the efficient:
num.digits.sum
But for numbers up to 5 digits (or digit sums up to 47) we can already do:
num.to_s.sum%48
which is just 1 character longer.
Unfortunately, most of what I do now is machine learning, and Python wrappers for underlying C++ code have by far more support than Ruby. (Ruby does have some great ML projects and libraries though).
http://www.somatic.io/blog/tensorflow-is-coming-to-ruby
It's a Ruby wrapper for the popular Google TensorFlow ML library. It will probably be completed before this autumn because it was originally a GSOC project (and couldn't be admitted because it was found to be missing some Google requirements at the last moment). It's now crowdfunded but it seems that Google is still offering some degree of support to interested developers [1].
In the meanwhile also check this out https://gist.github.com/gbuesing/865b814d312f46775cda "Resources for Machine Learning in Ruby", some of which are again wrappers around popular ML C libraries, thus removing the problem about sheer speed.
Why does Ruby have 4 different regexp match functions?
Regexp#match?: 2630002.5 i/s Regexp#===: 872217.5 i/s - 3.02x slower Regexp#=~: 859713.0 i/s - 3.06x slower Regexp#match: 539361.3 i/s - 4.88x slower
match returns match data, and sets the $~ variable
=== returns true or false, setting the $~ variable
=~ returns integer (position) or nil, setting $~
The newest one match? returns a boolean, not setting $~
Can anyone shed any light on this, because my first attempts at grok'ing this change have me really blown away.
If you have issue with this sort of thing, you should go to Elixir. ;)
Though, I too had to dig into it the first time I saw use of these special vars to gain confidence that I wasn't introducing a world of pain when we hit load.
123.digits # => [3, 2, 1]So this ordering is least to most significant.
I believe Matz has said that it is on the agenda for Ruby 3.0: that it will have static typing and that it will be optional.