I know my question would sound silly but I'm new to Lua so I'm trying to make the best practice as I can.
function wait(n)
local start = os.time()
repeat until os.time() > start + n
end
function hi(x)
while x do
print("Hi")
wait(.5)
end
end
hi(true)
For example, I want to turn off the function "hi" after running for 6 seconds and re-enable it after stopping for 2 seconds, how can I do it? Thank you so much!
Try this changes...
function wait(n)
local start = os.clock()
repeat until os.clock() > start + n
end
function hi(x)
for i = 1, x do
print("Hi")
wait(.5)
end
end
hi(4) -- With the hardcoded wait(.5) this will end after 2s
One warning.
Lua is fast so wait() will run in high performance mode.
Let it run by hi(120) for a minute will also run your fans in high cooling mode.
...it is better to have a more CPU friendly wait/sleep.
Easy Peasy with LuaJIT: https://luajit.org/ext_ffi_tutorial.html
I'm implementing a crash function in a GenServer to test the behavior of the supervisor and registry that will manage this process. Work is done in Elixir but I believe it may also concern Erlang.
I could have called raise() but in the first place I implemented 1/0 as the reason for crash. The compiler being a smart guy, for the following code:
def handle_cast(:crash, state) do
a = 1 / 0
{:noreply, state}
end
I got the warning:
warning: this expression will fail with ArithmeticError
lib/xyz/worker.ex:47
Fair. After all, even old C or C++ compilers were able to detect this kind of things. I tried a library call replacing a = 1 / 0 by a = 1 / :math.sin(0). Same warning. My curiosity woke up and I tried different things with the same outcome. Actually, it looks like this is not so easy to fool the compiler! Eventually, I put:
a = 1 / Enum.reduce([0, 1, -1], 0, fn(n, acc) -> n+acc end)
and got a different warning:
warning: the result of the expression is ignored (suppress the warning by assigning the expression to the _ variable)
lib/xyz/worker.ex:50
line 50 being a = 1 / Enum.reduce(...).
I spent a couple of hours trying different things with always getting either warning.
I believe the first one is raised because the compiler is able to precalculate the result out of constant arguments and of function type and inline eventually the operation 1 / 0.
Yet I don't understand the second warning. In one of the tests, I wrote :
def handle_cast(:crash, state) do
a = 1 / Enum.reduce([0, 1, -1], 0, fn(n, acc) -> n+acc end)
# {:noreply, state}
end
which actually suppresses the warning, but I really don't understand why.
NB.1: Versions:
maurice#mickey> elixir -v
Erlang/OTP 20 [erts-9.2] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false]
Elixir 1.6.1 (compiled with OTP 19)
NB.2: I'm aware of this question, yet I don't think the reply applies here.
For the time being, I'll be calling raise(...)...
Short version
The warning is actually telling you what to do: replace a = ... with _ = ....
Long version
In your examples at hand you assign the result of the operation to a variable called a. The compile notices that you never use that variable again, so it complains about it.
Elixir knows a "special" variable for that case called _. When doing _ = ... or def my_function(_, second_paramter) you basically tell the compiler:
I don't want to use that value, so please don't complain
To provide more information about the ignored value, you can also prefix a variable with an underscore (_), which serves the same purpose. In your case that could be _a = ....
This is mainly useful when ignoring arguments in a function, without leaving the reader to guess what that argument was about. So def get(:thing, _) could become def get(:thing, _opts).
Then you asked why the commented out version didn't produce that error. The answer to that lies in the fact that the return value of a function is equal to the last statement of that function.
So this function
def my_function do
1
2
3
end
returns 3, while this function
def my_function do
:a
:b
end
returns :b. As such in your example
def handle_cast(:crash, state) do
a = 1 / Enum.reduce([0, 1, -1], 0, fn(n, acc) -> n+acc end)
# {:noreply, state}
end
You commented out the # {:noreply, state} tuple and the a = ... statement becomes the last one in the function. Since now you create the variable a and evaluate it as part of the "return", the compiler stops complaining.
On the other hand, a fair case could be made that a variable assignment in the last line of a function is useless. So this might actually warrant a low priority issue on GitHub.
Fool the compiler till the end, reassign state variable:
def handle_cast(:crash, state) do
state = Enum.reduce([0, 1, -1], 0, fn(n, acc) ->
n + acc
end)
{:noreply, state}
end
That way the compiler will think state assignment is necessary (since it’s used as a return value.)
Program:
def inc(n)
n + 1
end
sum = 0
threads = (1..10).map do
Thread.new do
10_000.times do
sum = inc(sum)
end
end
end
threads.each(&:join)
p sum
Output:
$ ruby MutualExclusion.rb
100000
$
My expected output of above program is less than 100,000. Because, the above program create 10 threads and each of the thread
update the shared variable 'sum' to 10,000 times. But during execution of the program, mutual exclusion will definitely happen. Because,
mutual exclusion is not handled here. So I expect less than 100,000 as output. But it gives exactly 100,000 as output. How it is
happened ? Who handle the mutual exclusion here ? And how I experiment this problem(ME).
The default interpreter for Ruby (MRI) doesn't execute threads in parallel. The mechanism that's preventing your race condition from introducing casually unexpected behavior is the Global Interpreter Lock (GIL).
You can learn more about this, including a very similar demonstration, here: http://www.jstorimer.com/blogs/workingwithcode/8085491-nobody-understands-the-gil
Lua in ComputerCraft 1.5
This seems to work but the recursive loops is breaking after 4 or 5 times running.
Cannot seem to see why.
Am i doing something incredibly wrong here?
Full Code
Snippet for the loop:
x = 1
function loop()
if x > 0 then
getTarg()
derp1()
sleep(2.9)
monInit()
loop()
end
end
loop()
It looks as though you are not even using the X var... so why don't you try this... this is a more effective way to keep doing the same thing over and over
while true do
getTarg()
derp1()
sleep(2.9)
monInit()
end
This might be a silly question. But, I am a newb... How can you have a multi-line code in the interactive ruby shell? It seems like you can only have one long line. Pressing enter runs the code. Is there anyway I can skip down to the next line without running the code? Again, sorry if this is a dumb question. Thanks.
This is an example:
2.1.2 :053 > a = 1
=> 1
2.1.2 :054 > b = 2
=> 2
2.1.2 :055 > a + b
=> 3
2.1.2 :056 > if a > b #The code ‘if ..." starts the definition of the conditional statement.
2.1.2 :057?> puts "false"
2.1.2 :058?> else
2.1.2 :059 > puts "true"
2.1.2 :060?> end #The "end" tells Ruby we’re done the conditional statement.
"true" # output
=> nil # returned value
IRB can tell us the result of the last expression it evaluated.
You can get more useful information from here(https://www.ruby-lang.org/en/documentation/quickstart/).
One quick way to do this is to wrap the code in if true. Code will run when you close the if block.
if true
User.where('foo > 1')
.map { |u| u.username }
end
If you are talking about entering a multi-line function, IRB won't register it until you enter the final end statement.
If you are talking about a lot of individual expressions such as
x = 1
y = 2
z = x + y
It's OK if IRB executes each as you enter it. The end result will be the same (for time-insensitive code of course). If you still want a sequence of expressions executed as fast as possible, you can simply define them inside of a function, and then run that function at the end.
def f()
x = 1
y = 2
z = x + y
end
f()