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!
Related
I have limited knowledge of lua and would like to make an or statement.
However, I don't know the exact syntax.
Would the code below work correctly?
if text == "/teamspeak" or text == "/ts" then
If not please let me know on the correct syntax of the statement.
Yes, the statements are correct. You do not have any syntactical errors there, though you might want to check whether text contains only the command or the whole string (as is the case with ptokax). You might also want to check that the command is uppercase/lowercase or mixed-casing.
local sCmd = text:lower()
if sCmd == "/ts" or sCmd == "/teamspeak" then
...
end
Lua uses the keyword or for or statements.
I recommend reading the Lua language reference.
Your code would work correctly if you terminate the if then statement with end.
Best way is to try it yourself. If you do not have Lua installed you can use http://www.lua.org/demo.html
And please note that nil is not the same as false! Many Lua beginners have problems here.
That statement should work, though I suggest converting the string to lowercase first, as jhpotter92 already suggested.
A typical problem in cases like this is when the order the language deals with operands is not the one you'd expect; if, for example, lua were to evaluate the or before the == operator (which it doesn't, see reference) that code would not work. Therefore it is never a bad idea to write your code like this
if (text == "/teamspeak") or (text = "/ts") then <...> end
just to be sure lua does things in the correct order.
If you ever find yourself in this kind of situation again, and you don't want to wait for someone to respond to your question, you can just start lua in interactive mode (assuming you have lua installed on your system, which is very helpful for everyone who wants to learn/code in lua) and type something like
> text = "/teamspeak"
> if text == "/teamspeak" or text == "/ts" then print "true ♥" end
In this example, the console will output "true ♥". Repeat this with text="/ts" and text="some other string" and see if the line of code behaves as it should.
This shouldn't take you longer than 5 minutes (maybe +5 minutes to install lua first)
I'm doing API calls that will conditionally return a couple different elements. My code is currently:
if array['productId']
value = array['productId'][0]
end
I feel like there is a more succinct way of doing this. Some Ruby magic.
A better way :
value = array['productId'][0] if array['productId']
However, array['productId'][0] is not ruby natural. What does your array consist of ?
Since Ruby 2.3.0, the shortest way is Array#dig:
array.dig('productId', 0)
http://ruby-doc.org/core-2.3.0_preview1/Array.html#method-i-dig
I am not sure if you are using value just temporarily or actually using it later, and what you want to do with value when the condition is not met. If you want to return nil for missing keys, then
array['productId'].to_a[0]
can work. Otherwise, SpyrosP's answer will be the best.
This might be a bit pedantic, but to make sure it works in all circumstances, you should not check 'not-nil', but rather that it is indexable; something like this:
value = array['productId'][0] if array['productId'].is_a? Array
Or even better:
value = array['productId'][0] if array['productId'].respond_to? '[]'
Otherwise your code will fail if array['productId'] == 2 (which on the other hand seems reasonable, given the key used - I would have gone product_ids instead).
You could use a ternary:
value = array['productId'].nil? ? nil : array['productId'][0]
Your code pattern looks OK; it's possible to be slightly shorter...
value = (t = x['productId']) && t[0]
Using the maybe pattern of Ick, terse and explicit:
value = array['productId'].maybe[0]
While I think your code is fine (although I'd prefer SpyrosP's one-line version), you have some possibilities:
Rails has Object#try, which would let you do either array['productId'].try(:[], 0) or array['productId'].try(:at, 0).
Some people like the andand gem, which defines Object#andand and is used like array['productId'].andand[0].
Ha, I love all the options here. But since I didn't see what I use most, I'll add one more!
value = array['productId'] && array['productId'].first
(I prefer .first to [0] because it reads a little better)
This presumes you'll have an array in array['productId'], which is the right way to do it (rather than type-checking).
Otherwise, the biggest diference between this and your original code, is that this results in value having nil assigned to it if the array doesn't have anything, whereas your original results in value not being defined (which may cause errors, depending on how you use it down the road).
Hope that helps!
I feel pretty dumb having to ask this, but it's had me stumped way too long. Attempting to run the following, I get
finance.rb:1: syntax error, unexpected kDEF, expecting $end
def get_sign(input)
return "+" if input.include? "+"
return "-" if input.include? "-"
end
def get_account_name(input)
if input.split[0] == "new"
return input.split.reject{|x| x == "new" or x == "account"}[0]
else
return input.split[0]
end
end
If I wrap them in a class, it just expects <, \n, or ; instead of $end.
Ruby 1.8.7 and 1.9 (via Macruby) give the same error. Removing the second method seems to get it working. Someone, please enlighten me; this seems like a really fundamental misunderstanding of something on my part.
I don't get this error if I copy/paste your contents from this question into a new file. If you do so (copy/paste from this web page into a new file and save that) do you still get the error? If not, perhaps you have some garbage whitespace in your file?
Added as answer because another user may find this question with a similar problem and not read through all the comments to find the solution.
There were two good reasons why Ruby 1.8 didn't support certain kinds of overloading like ||/or, &&/and, !/not, ?::
Short circuit semantics cannot be implemented with methods in Ruby without very extensive changes to the language.
Ruby is hard coded to treat only nil and false as false in boolean contexts.
The first reason doesn't apply to !/not but second still does. It's not like you can introduce your own kinds of boolean-like objects using just ! while &&/|| are still hard-coded. For other uses there's already complementarity operator ~ with &/|.
I can imagine there's a lot of code expecting !obj to be synonymous with obj ? false : true, and !!obj with obj ? true : false - I'm not even sure how is code supposed to deal with objects that evaluate to true in boolean context, but ! to something non-false.
It doesn't look like Ruby plans to introduce support for other false values. Nothing in Ruby stdlib seems to override ! so I haven't found any examples.
Does it have some really good use I'm missing?
Self-replying. I found one somewhat reasonable use so far. I can hack this to work in 1.9.2 in just a few lines:
describe "Mathematics" do
it "2 + 2 != 5" do
(2+2).should != 5
end
end
Before 1.9.2 Ruby this translates to:
describe "Mathematics" do
it "2 + 2 != 5" do
((2+2).should == 5) ? false : true
end
end
But as return value gets thrown away we have no ways of distinguishing == 5 from != 5 short of asking Ruby for block's parse tree. PositiveOperatorMatcher#==(5) would just raise ExpectationNotMetError exception and that would be it. It seems should !~ /pattern/, should !be_something etc. can also be made to work.
This is some improvement over (2+2).should_not == 5, but not really a big one. And there's no way to hack it further to get things like (2+2).should be_even or be_odd.
Of course the right thing to do here would be asking Ruby for parse tree and macro-expanding that. Or using debug hooks in Ruby interpreter. Are there use cases better than this one?
By the way, it wouldn't be enough to allow overrides for ! while translating !=/!~ the old way. For !((2+2).should == 5) to work #== cannot raise an exception before ! gets called. But if #== fails and ! doesn't get run execution will simply continue. We will be able to report assertion as failed after block exits, but at cost of executing test after the first failure. (unless we turn on ruby debug hooks just after failed assertion to see if the very next method call is !self, or something like that)
I am very new to Ruby, so please accept my apologies if this question is wierd
I tried puts 5-8.abs which returned -3, and then I tried puts (5-8).abs which returned 3.
What is happening exactly when I try puts 5-8.abs, it seems like abs is ignored?
It's a precedence issue. The method call, .abs, is evaluated before the minus operator.
5-8.abs # => equivalent to 5-(8.abs)
Think of it this way - whitespace is not significant in Ruby. What would you expect to happen if you saw this?
5 - 8.abs
Here's a reference for Ruby precedence rules.
Method call (8.abs in this case)always has higher Precedence than operators (- in this case).
So, 5-8.abs translats to 5-(8.abs) = 5 - 8 = -3
5-8.abs seems to be doing 5-(8.abs) = 5-8 = -3 like you got.
Also, any time precedence is the least bit up in the air, explicit parenthesization helps.