p [1,2,3].map(&:abs)
p [1,2,3].map(:abs)
p [1,2,3].reduce(&:gcd)
p [1,2,3].reduce(:gcd)
Can someone pls explain why line 2 will throw an error, but not line 4.
This isn't a general syntactic thing related to Symbol or Symbol#&. It's a special case built into the implementation of Enumerable#reduce.
Related
I am learning OCaml and I'm a complete beginner at this point. I'm trying to get used to the syntax and I just spent 15 minutes debugging a stupid syntax error.
let foo a b = "bar";;
let biz = foo 2. -1.;;
I was getting an error This expression has type 'a -> string but an expression was expected of type int. I resolved the error, but it prompted me to learn what is the best way to handle this syntax peculiarity.
Basically OCaml treats what I intended as the numeric constant -1. as two separate tokens: - and 1. and I end up passing just 1 argument to foo. In other languages I'm familiar with this doesn't happen because arguments are separated with a comma (or in Scheme there are parentheses).
What is the usual way to handle this syntax peculiarity in OCaml? Is it surrounding the number with parentheses (foo 2. (-1.)) or there is some other way?
There is an unary minus operator ~-. that can be used to avoid this issue: foo ~-.1. (and its integer counterpart ~-) but it is generally simpler to add parentheses around the problematic expression.
In Perl, I often find myself using the following pattern:
croak "incompatible object given: $object"
unless $object->isa('ExampleObject') and $object->can('foo');
I tried to translate this into Ruby like this:
raise ArgumentError, "incompatible object given: #{object.inspect}"
unless object.is_a?(ExampleObject) and object.respond_to?(:foo)
But that does not work because Ruby interprets unless as the start of a new statement. As far as I understand, I can put a backslash at the end of the first line, but that looks ugly and feels wrong. I could also use a regular unless condition raise error end structure, but I like the style of the original form more. Is there a nice (and idiomatic) way to write this as a single statement in Ruby?
Can I put an if/unless clause on the next line in Ruby?
You can't. From page 107 (PDF page 127) of the final draft of ISO Ruby which usually isn't relevant, but basic things like this are and it also spares us from having to read parse.y:
unless-modifier-statement ::
statement [no line-terminator here] unless expression
This is pretty clear. It just doesn't get more similar to your Perl example than:
raise ArgumentError, "incompatible object given: #{object.inspect}" unless
object.is_a?(ExampleObject) and object.respond_to?(:foo)`
or:
raise ArgumentError, "incompatible object given: #{object.inspect}" \
unless object.is_a?(ExampleObject) and object.respond_to?(:foo)
Just as you feel wrong to put a backslash at the end to force a single line statement, it is wrong to use a single line statement when it extends beyond a single line.
This is not really a solution, I was sloppy when reading the question. The OP wants a solution without backslash.
You should be able to do this:
raise ArgumentError, "incompatible object given: #{object.inspect}" \
unless object.is_a?(ExampleObject) and object.respond_to?(:foo)
The \ characters tells ruby to keep reading as if there was no line break.
As far as I know there is no other way than a \, since otherwise, as you already said, Ruby thinks it's a new statement.
Keep in mind that style guides and conventions differ from language to language. In Ruby I'd not expect an if/unless statement in a line coming after it's code. In fact I even dislike putting if/unless at the end of a line, since it reverses the reading direction from If this, then that to that, if this (then what? Ah, I need to read back again), especially when the condition is more complex than raise 'foo' if bar.empty?.
In Perl and other languages though this might be different, since you have other conventions, style guides and this ;-thingy ;)
You would think that this would be an easy question, but I can't find the answer anywhere. >_<
Will Ruby throw syntax errors if my code is indented incorrectly? For example, would code like this work?
if str.blank?
str = "Hello World"
no_input = true
end
Obviously, this is bad style and I should indent correctly regardless. I want to know whether I can rule it out as the cause of a bug during debugging sessions.
Yes, it would work. Ruby only looks for the line breaks.
But since code readability is also very important, I'd say you should take care of whitespace if only for that sake.
Indentation is (Usually) a Stylistic Choice
In Ruby, indentation per se is not relevant, although the location of linebreaks and other whitespace may cause ambiguity for the parser or cause it to consider certain things as separate expressions when you didn't mean for them to be. Here-documents and multi-line strings are also areas where indentation will matter.
In all cases, the real question is "what does the parser see?" In your example, it should be functionally equivalent to the properly-indented code. However, if you really want to know what's going on under the hood, take a look at Ruby's Ripper module to see how your code is actually being parsed.
Ruby is not whitespace sensitive. Your code, although not pretty, will work.
However: http://www.ruby-forum.com/topic/56039
irb(main):001:0> a = ( 4 + 5 )
=> 9
irb(main):002:0> a = ( 4
irb(main):003:1> + 5 )
=> 5
irb(main):004:0> a = ( 4 +
irb(main):005:1* 5 )
=> 9
Someone asked about the splat operator yesterday, and I wanted to see the source code... would that be written in C or in Ruby? Where would it be found?
Some quick Google searching turned up that it's implemented in eval.c. You can find references to "splat" in a few places in the file, but I'm not familiar enough with the inner workings of Ruby to make any sense of it.
The splat operator is poorly documented in the core Ruby documentation as of Ruby 2.4. It's a core feature of the language, though, and the source code for the splat operator can be found in vm_eval.c under rb_yield_splat(VALUE values).
The unit test for rb_yield_splat makes it clearer what is happening:
it "yields with passed array's contents" do
ret = nil
#s.rb_yield_splat([1, 2]) { |x, y| ret = x + y }
ret.should == 3
end
Just tried to execute a small Lua script, but unfortunately I'm doing something wrong. I've no more ideas what the fault might be.
function checkPrime( n )
for i = 2, n-1, 1 do
if n % i == 0 then
return false
end
end
return true
end
The interpreter says:
lua: /home/sebastian/luatest/test.lua:3: `then' expected near `%'
I think it's not a big thing and perhaps it's quite clear what is wrong. But somehow I cannot see it at the moment.
There is probably some version problem, check your version of lua. The usage of '%' as an infix operator for modulo can only be used in Lua 5.1, in 5.0 it is not supported yet. Try using math.mod instead:
if math.mod(n,i) == 0 then
Edit: Also note that in 5.1, math.mod still exists, but it has been renamed to math.fmod. For now, the old name still works, but support will probably be removed in future versions.
Have you tried wrapping "n% i == 0" in parentheses? Stupid question, but sometimes overlooked!