I want to pre-increment a variable value in ruby but i can't.
in java we can do this
int a=50;
++a;
System.out.println(a);
but how to do this in ruby ?
if i do this it gives me error
a=50
1-=a
puts a
Use Ruby's Abbreviated Assignment
Ruby doesn't implement a ++ operator as such, either pre or post. However, you don't really need it, either. Since everything in Ruby is an expression, the following is idiomatic Ruby code that does what you likely expect in a more Ruby-centric way:
a = 50
p a+=1
#=> 51
This works because a+=1 increments the value of a, assigns the result back to a, and then returns the result. Under the hood, this is largely equivalent to writing:
a = 50
a = a + 1
Kernel.p(a)
but is shorter and easier to read because the abbreviated assignment is evaluated and passed as an argument to Kernel#p, where it's both sent to standard output and returned as a value.
For the sake of completeness, here are equivalent pieces of code for pre- and post-increment.
Java:
public class PreProIncrement
{
public static void main(String[] args)
{
int a = 50;
System.out.println(++a);
System.out.println(a);
System.out.println(a++);
System.out.println(a);
}
}
Ruby:
a = 50
p(a = a + 1) # or p(a+=1)
p(a)
a = p(a) + 1
p(a)
Both have the same output:
51
51
51
52
In Ruby, p a is used instead of puts a because p a displays and returns a, while puts a displays a but returns nil.
Related
A tidy number is a number whose digits are in non-decreasing order, e.g. 1234. Here is a way of finding tidy numbers written in Ruby:
def tidy_number(n)
n.to_s.chars.sort.join.to_i == n
end
p tidy_number(12345678) # true
p tidy_number(12345878) # false
I tried to write the same thing in Scala and arrived at the following:
object MyClass {
def tidy_number(n:Int) = n.toString.toList.sorted.mkString.toInt == n;
def main(args: Array[String]) {
println(tidy_number(12345678)) // true
println(tidy_number(12345878)) // false
}
}
The only way I could do it in Scala was by converting an integer to a string to a list and then sorting the list and going back again. My question: is there a better way? 'Better' in the sense there are fewer conversions. I'm mainly looking for a concise piece of Scala but I'd be grateful if someone pointed out a more concise way of doing it in Ruby as well.
You can use sorted on strings in Scala, so
def tidy_number(n: Int) = {
val s = n.toString
s == s.sorted
}
Doing it in two parts also avoids an extra toInt conversion.
I've never used ruby, but this post suggests you're doing it the best way
You can check each adjacent pair of digits to make sure that the first value is <= the second:
def tidy_number(n:Int) =
n.toString.sliding(2,1).forall(p => p(0) <= p(1))
Update following from helpful comments
As noted in the comments, this fails for single-digit numbers. Taking this and another comment together gives this:
def tidy_number(n:Int) =
(" "+n).sliding(2,1).forall(p => p(0) <= p(1))
Being even more pedantic it would be better to convert back to Int before comparing so that you don't rely on the sort order of the characters representing digits being the same as the sort order for the digits themselves.
def tidy_number(n:Int) =
(" "+n).sliding(2,1).forall(p => p(0).toInt <= p(1).toInt)
The only way I could do it in Scala was by converting an integer to a string to a list and then sorting the list and going back again. My question: is there a better way?
String conversion and sorting is not required.
def tidy_number(n :Int) :Boolean =
Iterator.iterate(n)(_/10)
.takeWhile(_>0)
.map(_%10)
.sliding(2)
.forall{case Seq(a,b) => a >= b
case _ => true} //is a single digit "tidy"?
Better? Hard to say. One minor advantage is that the math operations (/ and %) stop after the first false. So for the Int value 1234567890 there are only 3 ops (2 modulo and 1 division) before the result is returned. (Digits are compared in reverse order.)
But seeing as an Int is, at most, only 10 digits long, I'd go with Joel Berkeley's answer just for its brevity.
def tidyNum(n:Int) = {
var t =n; var b = true;
while(b && t!=0){b=t%10>=(t/10)%10;t=t/10};b
}
In Scala REPL:
scala> tidyNum(12345678)
res20: Boolean = true
scala> tidyNum(12343678)
res21: Boolean = false
scala> tidyNum(12)
res22: Boolean = true
scala> tidyNum(1)
res23: Boolean = true
scala> tidyNum(121)
res24: Boolean = false
This can work for any size with just the modification of type such as Long or BigInt in function signature like tidyNum(n:Long) or tidyNum(n:BigInt) as below:
def tidyNum(n:BigInt) = {
var t =n; var b = true;
while(b && t!=0){b=t%10>=(t/10)%10;t=t/10};b
}
scala> tidyNum(BigInt("123456789"))
res26: Boolean = true
scala> tidyNum(BigInt("1234555555555555555555555567890"))
res29: Boolean = false
scala> tidyNum(BigInt("123455555555555555555555556789"))
res30: Boolean = true
And the BigInt can be used for types Int, Long as well.
def success?
return #fhosts.empty? and #khosts.empty? and #shosts.any?
end
When I run that instance method, I get an error:
/home/fandingo/code/management/lib/ht.rb:37: void value expression
return #fhosts.empty? and #khosts.empty? and #shosts.any?
I'm confused by what's happening since this works
def success?
#fhosts.empty? and #khosts.empty? and #shosts.any?
# This also works
# r = #fhosts.empty? and #khosts.empty? and #shosts.any?
# return r
end
I'm coming from a Python background, and I don't want anything to do with implicit returns. Programming has plenty of landmines as it is.
If we have an arbitrary expression, E, that consists of boolean operations and and or together, here are some operations we could perform:
if E -- works
E -- works
* v = E -- works
return E -- broken
Why doesn't the last case work?
Edit: Actually v = E doesn't work. Only
v = Ei
is evaluated. Ei+1...k are ignored.
This is likely due to the very weak binding of and which causes it to parse out differently than you expect:
return x and y
This actually means:
(return x) and y
Since you're returning immediately it doesn't have a chance to evaluate the remainder of the expression.
Your version without return is correct:
x and y
This doesn't have a binding issue and is more idiomatic Ruby. Remember you only need to put an explicit return if you're trying to force an exit before the last line of the method. Being opposed to implicit returns is going to make your code look heavily non-Ruby. They're one of the reasons Ruby is so clean and simple, and how things like a.map { |v| v * 2 } works.
The When in Rome principle applies here. If you want to write Python-style Ruby you're going to be going against the grain. It's like saying "I don't like how you say X in your spoken language, so I'll just ignore that and do it my way."
This should also work:
return x && y
The && method is very strongly bound so return is the last thing evaluated here.
Or if you really want to use and for whatever reason:
return (x and y)
I am trying to make an RPN calculator. I have to implement my own .to_i and .to_f method. I cannot use send, eval, Float(str) or String(str) method. The assignment is done, but I still want to know how to implement it.
The input: atof("255.25") as string type
Output: 255.55 as float type
Here is my code for atoi
ASCII_NUM_START = 48 # start of ascii code for 0
def ascii_to_i(int_as_str)
array_ascii = int_as_str.bytes
converted_arr = array_ascii.map {|ascii| ascii - ASCII_NUM_START }
converted_arr.inject { |sum, n| sum * 10 + n }
end
def ascii_to_f(float_as_str)
???
end
I got it working doing the following (and utilizing your ascii_to_i function).
ASCII_NUM_START = 48 # start of ascii code for 0
def ascii_to_i(int_as_str)
array_ascii = int_as_str.bytes
converted_arr = array_ascii.map {|ascii| ascii - ASCII_NUM_START }
converted_arr.inject { |sum, n| sum * 10 + n }
end
def ascii_to_f(float_as_str)
int_split = float_as_str.split(".")
results = []
int_split.each { |val| results << ascii_to_i(val) }
results[0] + (results[1] / (10.0 ** int_split.last.length))
end
I can see you have made a reasonable effort at ascii_to_i.
The code for ascii_to_f can be similar, and in addition you will need to divide the result by the number of decimal places that you have processed.
Probably the easiest adaptation is:
find the position of the . character (ASCII code 46) in the String, save that as a variable
remove the . character (ASCII code 46) from your array of bytes
calculate the Integer value from the array of bytes as before
divide by 10.0 (must be a Float) to the power of (the length of the remaining array minus the position you found the . in).
I am not giving code, because it is an assignment. See if you can figure out the correct syntax, looking at documentation for the Array class for finding the position of a specific value, for deleting a specific value, and for getting length of the array.
Consider the following code snippet:
class Example
def my_attr=(value)
#_my_attr = value
#_my_attr * 3
end
end
I expect the expression Example.new.my_attr = 5 to return 15, but that turns out to be wrong. The original return value is always returned, even when I call the = method explicitly:
Example.new.my_attr = 5 # => 5
Example.new.my_attr=(5) # => 5
How and why does Ruby do this? Does Ruby treat methods that end in = specially, or is it some other mechanism? I guess this precludes chaining on return values of = methods, right? Is there a way to make Ruby behave differently, or is this just how it is?
Update: Credit to #jeffgran for this:
Example.new.send(:my_attr=, 5) # => 15
This is a workaround, but on another level even more perplexing, since that would mean send is clearly not always equivalent in behavior to calling a method directly.
This is how assignment works; the return value is ignored, and the result of an assignment expression is always the right-hand value. This is a fundamental feature of Ruby's grammar. left-hand side = right-hand side will always evaluate to right-hand side, regardless of whether left hand side is a variable (x), a method (object.x), a constant (X) or any expression.
Source: Programming Languages | Ruby
IPA Ruby Standardization WG Draft, 11.4.2.2.5, Single method assignments
Consider chaining of assignments, x = y = 3.
For this to work correctly, the result of y = 3 must be 3, regardless of the actual value returned by the y= method. x = y = 3 is meant to read as y = 3; x = 3, not as y = 3; x = y which is what would be implied if the return value from y= was treated as the result of y = 3.
Or consider all the other places assignment can be used. Sometimes, instead of this...
obj.x = getExpensiveThing()
if obj.x
...
... we write this ...
if obj.x = getExpensiveThing()
This couldn't work if the result of obj.x = ... could be any arbitrary thing, but we know it will work because the result of obj.x = y is always y.
Update
A comment on the question states:
Interesting, I wasn't aware of this scenario. It seems that method= returns whatever input is given...
No, it's an important distinction to make. This has nothing to do with the return value of method assignment, and it definitely does not "return whatever input is given", it returns whatever you tell it to return.
The whole point is that the return value is ignored by the grammar of the language; assignment doesn't evaluate to the return value of the attr= method, but the return value still exists as evidenced by the question itself: Example.new.send(:my_attr=, 5) # => 15. This works because it is not assignment. You're side-stepping that part of the Ruby language.
Update again
To be clear: x and y in my examples shouldn't be interpreted as literal Ruby variables, they are place holders for any valid left-hand side of an assignment. x or y could be any expression: a, obj.a, CONSTANT_A, Something::a, #instance_a, it's all the same. The value of assignment is always the right-hand side.
I'm trying to figure out how Ruby handles chaining enumerators that yield multiple arguments. Take a look at this snippet:
a = ['a', 'b', 'c']
a.each_with_index.select{|pr| p pr}
# prints:
# ["a", 0]
# ["b", 1]
# ["c", 2]
a.each_with_index.map{|pr| p pr}
# prints:
# "a"
# "b"
# "c"
Why does select yield the arguments as an array, whereas map yields them as two separate arguments?
Try:
a.each_with_index.map{|pr,last| p "pr: #{pr} last: #{last}"}
map is automatically deconstructing the values passed to it. The next question is why is it doing this deconstruction and select isn't?
If you look at the source given on the Rdoc page for Array they're virtually identical, select only differs in that it does a test on the value yielded. There must be something happening elsewhere.
If we look at the Rubinius source (mainly because I'm better with Ruby than C;) for map (aliased from collect) it shows us:
each do |*o|
so it's splatting the arguments on the way through, whereas select (aliased from find_all) does not:
each do
again, the design decision as to why is beyond me. You'll have to find out who wrote it, maybe ask Matz :)
I should add, looking at the Rubinius source again, map actual splats on each and on yield, I don't understand why you'd do both when only the yield splat is needed:
each do |*o|
ary << yield(*o)
end
whereas select doesn't.
each do
o = Rubinius.single_block_arg
ary << o if yield(o)
end
According to the MRI source, it seems like the iterator used in select splats its arguments coming in, but map does not and passes them unpacked; the block in your latter case silently ignores the other arguments.
The iterator used in select:
static VALUE
find_all_i(VALUE i, VALUE ary, int argc, VALUE *argv)
{
ENUM_WANT_SVALUE();
if (RTEST(rb_yield(i))) {
rb_ary_push(ary, i);
}
return Qnil;
}
The iterator used in map:
static VALUE
collect_i(VALUE i, VALUE ary, int argc, VALUE *argv)
{
rb_ary_push(ary, enum_yield(argc, argv));
return Qnil;
}
I'm pretty sure the ENUM_WANT_SVALUE() macro is used to turn the value passed into the block into a splat array value (as opposed to a tuple with the latter arguments silently ignored). That said, I don't know why it was designed this way.
From the discourse so far, it follows that we can analyze the source code, but we do not know the whys. Ruby core team is relatively very responsive. I recommend you to sign in at http://bugs.ruby-lang.org/issues/ and post a bug report there. They will surely look at this issue at most within a few weeks, and you can probably expect it corrected in the next minor version of Ruby. (That is, unless there is a design rationale unknown to us to keep things as they are.)
Let's see MRI source in enum.c. As #PlatinumAzure said, the magic happens in ENUM_WANT_SVALUE():
static VALUE
find_all_i(VALUE i, VALUE ary, int argc, VALUE *argv)
{
ENUM_WANT_SVALUE();
if (RTEST(rb_yield(i))) {
rb_ary_push(ary, i);
}
return Qnil;
}
And we can find this macro actually is: do {i = rb_enum_values_pack(argc, argv);}while(0).
So Let's continue dive into rb_enum_values_pack function:
VALUE
rb_enum_values_pack(int argc, VALUE *argv)
{
if (argc == 0) return Qnil;
if (argc == 1) return argv[0];
return rb_ary_new4(argc, argv);
}
See? The arguments are packed by rb_ary_new4, which is defined in array.c.