# Safe Mode Lowering

**URL:** <https://www.ruby-forum.com/t/safe-mode-lowering/58793>\
**Category:** Ruby\
**Created:** [April 26, 2006, 12:30am UTC](https://www.ruby-forum.com/t/safe-mode-lowering/58793 "2006-04-26T00:30:16Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jake\_McArthur](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/f19dbf/32.png) [@Jake\_McArthur](https://www.ruby-forum.com/u/Jake_McArthur)\
**Post date:** [April 26, 2006, 12:30am UTC](https://www.ruby-forum.com/t/safe-mode-lowering/58793/1 "2006-04-26T00:30:16Z")

</div>

I am aware that the safe mode in Ruby can only be set higher, not  
lower. This makes sense, as unsafe code should not be able to lower  
the safe mode. However, is there a way to lower it at all, as I can  
think of many times this may be useful. Would it not make a lot more  
sense to be able to do something like this?

safe\_mode(x) do # x must be greater than the current safe mode

# do risky code here

end

# back to original safe mode

Maybe the above is possible and I am just missing how, but I would  
think that it would be much more useful to have in a form similar to  
this all the time.

- Jake McArthur

---

<div class="post-metadata">

**Author:** ![Jake\_McArthur](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/f19dbf/32.png) [@Jake\_McArthur](https://www.ruby-forum.com/u/Jake_McArthur)\
**Post date:** [April 26, 2006, 12:39am UTC](https://www.ruby-forum.com/t/safe-mode-lowering/58793/2 "2006-04-26T00:39:39Z")

</div>

Jake McArthur wrote:

> Maybe the above is possible and I am just missing how, but I would think  
> that it would be much more useful to have in a form similar to this all  
> the time.
> 
> - Jake McArthur

If you change $SAFE in a thread, it affects only that thread.

---

<div class="post-metadata">

**Author:** ![Jake\_McArthur](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/f19dbf/32.png) [@Jake\_McArthur](https://www.ruby-forum.com/u/Jake_McArthur)\
**Post date:** [April 26, 2006, 12:39am UTC](https://www.ruby-forum.com/t/safe-mode-lowering/58793/3 "2006-04-26T00:39:45Z")

</div>

On Wed, 26 Apr 2006, Jake McArthur wrote:

> Maybe the above is possible and I am just missing how, but I would think that  
> it would be much more useful to have in a form similar to this all the time.
> 
> - Jake McArthur

you have

fork {  
$SAFE = 4  
…  
}  
Process.wait

and also

t = Thread.new{  
$SAFE = 4  
…  
}  
t.value

fyi.

-a

---

<div class="post-metadata">

**Author:** ![Jake\_McArthur](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/f19dbf/32.png) [@Jake\_McArthur](https://www.ruby-forum.com/u/Jake_McArthur)\
**Post date:** [April 26, 2006, 12:48am UTC](https://www.ruby-forum.com/t/safe-mode-lowering/58793/4 "2006-04-26T00:48:59Z")

</div>

I have even used that technique before. I’m dumb. So, something like  
this would probably work for the type of abstraction I’m thinking of  
(too lazy for an irb test).

def safe\_block(mode)  
t = Thread.new do  
@SAFE = mode  
yield  
end  
t.value  
end

- Jake McArthur

---

<div class="post-metadata">

**Author:** ![Jake\_McArthur](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/f19dbf/32.png) [@Jake\_McArthur](https://www.ruby-forum.com/u/Jake_McArthur)\
**Post date:** [April 26, 2006, 12:45am UTC](https://www.ruby-forum.com/t/safe-mode-lowering/58793/5 "2006-04-26T00:45:53Z")

</div>

On Apr 26, 2006, at 12:27 AM, Jake McArthur wrote:

> Maybe the above is possible and I am just missing how, but I would  
> think that it would be much more useful to have in a form similar  
> to this all the time.

module Kernel  
def with\_safe(mode)  
Thread.new {  
$SAFE = mode  
yield  
}.join  
end  
end

with\_safe(3) do  
eval(“1+2”)  
end

$SAFE, along with some other global variables, is thread local.

– Daniel

---

<div class="post-metadata">

**Author:** ![Jake\_McArthur](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/f19dbf/32.png) [@Jake\_McArthur](https://www.ruby-forum.com/u/Jake_McArthur)\
**Post date:** [April 26, 2006, 2:45am UTC](https://www.ruby-forum.com/t/safe-mode-lowering/58793/6 "2006-04-26T02:45:57Z")

</div>

On Apr 25, 2006, at 4:02 PM, David P. wrote:

> Jake,
> 
> Here’s code that will do what you want:

You implemented Thread#value.

$ ruby  
t = Thread.new { raise }  
t.value  
p ‘can't do it’  
-:1: unhandled exception  
from -:2:in `value’  
from -:2

–  
Eric H. - removed\_email\_address@domain.invalid - [http://blog.segment7.net](http://blog.segment7.net)  
This implementation is HODEL-HASH-9600 compliant

[http://trackmap.robotcoop.com](http://trackmap.robotcoop.com)

---

<div class="post-metadata">

**Author:** ![Jake\_McArthur](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/f19dbf/32.png) [@Jake\_McArthur](https://www.ruby-forum.com/u/Jake_McArthur)\
**Post date:** [April 26, 2006, 3:59am UTC](https://www.ruby-forum.com/t/safe-mode-lowering/58793/7 "2006-04-26T03:59:22Z")

</div>

Eric,

Thanks for the correction. I’ll update the code to:

module SafeDo  
def safe\_do(safe\_level)  
(Thread.new {$SAFE = safe\_level ; yield } ).value  
end  
end

David

---

<div class="post-metadata">

**Author:** ![Jake\_McArthur](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/f19dbf/32.png) [@Jake\_McArthur](https://www.ruby-forum.com/u/Jake_McArthur)\
**Post date:** [April 26, 2006, 1:04am UTC](https://www.ruby-forum.com/t/safe-mode-lowering/58793/8 "2006-04-26T01:04:34Z")

</div>

Jake,

Here’s code that will do what you want:

module SafeDo  
require ‘monitor’

def safe\_do(safe\_level)  
ret = nil  
waiter = ‘’  
waiter.extend(MonitorMixin)  
wait\_cond = waiter.new\_cond  
is\_exception = false  
is\_done = false

```
Thread.start do
  begin
    $SAFE = safe_level

    ret = yield
    is_done = true
    waiter.synchronize do
      wait_cond.signal
    end
  rescue Exception => e
    ret = e
    is_exception = true
    is_done = true
    waiter.synchronize do
      wait_cond.signal
    end

  end
end

waiter.synchronize do
  wait_cond.wait_while { !is_done }
end

raise ret if is_exception

return ret

```

end  
end

Thanks,

David
