0

When I execute a script in IPython, by using run myscript.py, the names from the script are then available in the interactive interpreter for me to experiment with further.

In irb this doesn't seem to happen when I run the script using load 'myscript.rb'.

How do I keep the variables in scope in interactive ruby?

minrk
  • 37,545
  • 9
  • 92
  • 87
wim
  • 338,267
  • 99
  • 616
  • 750
  • which verion of ruby you are using? and can you be specific to your requirement? – Arup Rakshit Mar 27 '13 at 17:35
  • wim@wim-desktop:~$ ruby --version ruby 1.8.7 (2011-06-30 patchlevel 352) [x86_64-linux] wim@wim-desktop:~$ irb --version irb 0.9.5(05/04/13) – wim Mar 27 '13 at 17:37

2 Answers2

2

Local variables are local to the scope they are defined in. That's why they are called local variables. If you define a local variable in the script myscript.rb, then it will be defined inside that scope and nowhere else. That's the whole point of local variables.

If you want a variable that is available globally, use a global variable. Or maybe an instance variable of the top-level main object.

Jörg W Mittag
  • 363,080
  • 75
  • 446
  • 653
  • I don't understand, if I have a file `foo.py` with just the line `s = 'hello world'` in it, that is a global variable. If I rename the file to `foo.rb` it's now a local variable?? – wim Mar 27 '13 at 17:38
  • 3
    Yes, it is. Because you are talking about two completely unrelated programming languages which have absolutely nothing whatsoever to do with each other. They have different syntax, different semantics, a different type system, a different object system. `s` is *never* a global variable in Ruby. In Ruby, global variables *always* start with a `$` sign. – Jörg W Mittag Mar 27 '13 at 17:41
  • OK, fair enough, so is there any way to run my ruby script which is bringing names into scope in irb? – wim Mar 27 '13 at 17:43
  • I just found I could get what I was looking for with a glorified copy and paste using `eval File.read('foo.rb')` – wim Mar 27 '13 at 17:49
  • 2
    Yes, that works in Ruby 1.8, because `eval` leaks its scope. However, that bug was fixed in Ruby 1.9. – Jörg W Mittag Mar 27 '13 at 18:01
  • I'm un-accepting this answer because, whilst it's a clear explanation, it doesn't really solve my problem. I want to experiment with variables defined in a script from within irb, without needing to modify them into global variables. – wim May 29 '13 at 06:10
1

The answer I found while looking that this problem was to use a global variable or a class or function.

So for example, if I am using watir and I have a browser object I am interacting with, I can get it out of a test script with the following:

Global Variables

watir_test.rb

require "watir-webdriver"

browser = Watir::Browser.new :chrome
$b = browser

# all sorts of preliminary stuff I do on the browser object

# end of my test script

Now after launching irb, I load the test file

irb(main):001:0> load './watir_test.rb'
irb(main):002:0> browser
NameError: undefined local variable or method `browser' for main:Object
    from (irb):2
    from C:/Ruby193/bin/irb:12:in `<main>'
irb(main):004:0> $b
=> #<Watir::Browser:0x..fd9200f9a url="http....">

Returned Element(s)

test_code.rb

    def test_code
        a = 5    
        return a
    end

> load 'test_code.rb'
> a = test_code()

Return + local_variables

Here is a neat example: https://stackoverflow.com/a/1961317/999943

Ruby local_variables returns :symbols?

def foo(((a, b, c, d), e, *f), g, *h)
  local_variables.sort.each do |lvar| puts "#{lvar} => #{eval(lvar).inspect}" end
end

foo([[1, 2, 3], 4, 5, 6], 7, 8, 9)
# a => 1
# b => 2
# c => 3
# d => nil
# e => 4
# f => [5, 6]
# g => 7
# h => [8, 9]
Community
  • 1
  • 1
phyatt
  • 18,472
  • 5
  • 61
  • 80