[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

global_variable_set (like instance_variable_set

Thomas Hafner

8/11/2007 3:39:00 PM

Hello,

how can a function global_variable_set(gvarname, value) be
implemented? It should be similiar to the already existing method
Object#instance_variable_set, but set global variables rather than
instance variables.

Regards
Thomas
14 Answers

Thomas Hafner

8/11/2007 4:04:00 PM

0

Thomas Hafner <thomas@hafner.NL.EU.ORG> wrote/schrieb <ap11p4-9nm.ln1@faun.hafner.nl.eu.org>:

> how can a function global_variable_set(gvarname, value) be
> implemented?

The function should behave like the following one, but not use
``eval'' if possible.

def global_variable_set(gvarname, value)
eval("#{gvarname.id2name}=value")
end

Regards
Thomas

Gregory Brown

8/11/2007 5:35:00 PM

0

On 8/11/07, Thomas Hafner <thomas@hafner.nl.eu.org> wrote:
> Hello,
>
> how can a function global_variable_set(gvarname, value) be
> implemented? It should be similiar to the already existing method
> Object#instance_variable_set, but set global variables rather than
> instance variables.

What problem do you need this for... it sounds like you could get by
with a different (and better) approach, but we'd need to know a little
more about what you're trying to do.

Marc Heiler

8/12/2007 6:29:00 AM

0

> What problem do you need this for... it sounds like you could get by
> with a different (and better) approach, but we'd need to know a little
> more about what you're trying to do.


I believe for the record, a non-eval solution will be interesting to see
either way, even if he would use another (better) approach :-)
--
Posted via http://www.ruby-....

Eric Hodel

8/12/2007 9:07:00 AM

0

On Aug 11, 2007, at 23:29, Marc Heiler wrote:
>> What problem do you need this for... it sounds like you could get by
>> with a different (and better) approach, but we'd need to know a
>> little
>> more about what you're trying to do.
>
>
> I believe for the record, a non-eval solution will be interesting
> to see
> either way, even if he would use another (better) approach :-)

$ ruby
require 'rubygems'
require 'inline'

module Kernel
inline :C do |builder|
builder.include '"ruby.h"'

builder.c <<-'EOF'
static VALUE
global_variable_set(char * varname, VALUE object) {
return rb_gv_set(varname, object);
}
EOF
end
end

p global_variable_set 'foo', 5
-:17: warning: parenthesize argument(s) for future version
p $foo
# I hit ^D here
5D
5


--
Poor workers blame their tools. Good workers build better tools. The
best workers get their tools to do the work for them. -- Syndicate Wars



Thomas Hafner

8/12/2007 9:19:00 PM

0

"Gregory Brown" <gregory.t.brown@gmail.com> wrote/schrieb <b37300880708111035o2af744e1g2411e061054095ee@mail.gmail.com>:

> What problem do you need this for... it sounds like you could get by
> with a different (and better) approach, but we'd need to know a little
> more about what you're trying to do.

Agreed that that there might be a better solution for the original
problem, but sometimes an intermediate problem becomes interesting per
se. Anyway, the original question is how to find a single, more
abstract function replacing these ones:

def with_output_to_string
$stdout, tmp = StringIO.new, $stdout
yield
$stdout, tmp = tmp, $stdout
tmp.rewind
tmp.read
end

def with_error_to_string
$stderr, tmp = StringIO.new, $stderr
yield
$stderr, tmp = tmp, $stderr
tmp.rewind
tmp.read
end

The only difference is $stdout vs. $stderr, so the idea was to pass
:$stdout resp. :$stderr as parameter.

Regards
Thomas

Gregory Brown

8/12/2007 9:40:00 PM

0

On 8/12/07, Thomas Hafner <thomas@hafner.nl.eu.org> wrote:
> "Gregory Brown" <gregory.t.brown@gmail.com> wrote/schrieb <b37300880708111035o2af744e1g2411e061054095ee@mail.gmail.com>:
>
> > What problem do you need this for... it sounds like you could get by
> > with a different (and better) approach, but we'd need to know a little
> > more about what you're trying to do.
>
> Agreed that that there might be a better solution for the original
> problem, but sometimes an intermediate problem becomes interesting per
> se. Anyway, the original question is how to find a single, more
> abstract function replacing these ones:
>
> def with_output_to_string
> $stdout, tmp = StringIO.new, $stdout
> yield
> $stdout, tmp = tmp, $stdout
> tmp.rewind
> tmp.read
> end
>
> def with_error_to_string
> $stderr, tmp = StringIO.new, $stderr
> yield
> $stderr, tmp = tmp, $stderr
> tmp.rewind
> tmp.read
> end
>
> The only difference is $stdout vs. $stderr, so the idea was to pass
> :$stdout resp. :$stderr as parameter.

Interesting. Perhaps this is a direct translation of how you might do
this without an eval (untested):

module Kernel
def set_stdout(obj)
$stdout = obj
end

def set_stderr(obj)
$stderr = obj
end
end

def with_helper(msg)
temp = (msg == :stdout ? $stdout : $stderr)
send("set_#{msg}", StringIO.new)
yield
send("set_#{msg}",temp)
temp.rewind
temp.read
end

def with_output_to_string
with_helper(:stdout) { yield }
end

def with_error_to_string
with_helper(:stderr) { yield }
end

Of course, this doesn't sound like a great idea, as unless the real
problem is actually a whole lot more interesting, this is just
unnecessary generalization and doesn't clean things up any.

Are you looking to do this to test a codebase that writes to $stdout / $stderr?

It's perfectly reasonable to have a class or method definition like this:

class Foo
def initialize(out=$stdout,err=$stderr)
@out = out
@err = err
end

def print_to_stdout
@out.puts "something"
end

def print_to_stderr
@err.puts "something"
end
end


Now if you wanted to test that, you could pass in your StringIO
objects. Maybe you can draw some ideas from that, if not, it'd be
interesting to see what you're using this helper for.

Thomas Hafner

8/12/2007 10:12:00 PM

0

"Gregory Brown" <gregory.t.brown@gmail.com> wrote/schrieb <b37300880708121440j4e26fd21g4048d05057615b5e@mail.gmail.com>:

> Are you looking to do this to test a codebase that writes to $stdout
> / $stderr?

It's rather about using someone else's code. I'd prefer not to modify
it, because otherwise I had to merge every update.

> def print_to_stdout
> @out.puts "something"
> end
>
> def print_to_stderr
> @err.puts "something"
> end

Replacing ``puts'' by ``@out.puts'' is such a modification of foreign
code that I'd like to avoid.

Regards
Thomas

Gregory Brown

8/12/2007 10:26:00 PM

0

On 8/12/07, Thomas Hafner <thomas@hafner.nl.eu.org> wrote:
> "Gregory Brown" <gregory.t.brown@gmail.com> wrote/schrieb <b37300880708121440j4e26fd21g4048d05057615b5e@mail.gmail.com>:
>
> > Are you looking to do this to test a codebase that writes to $stdout
> > / $stderr?
>
> It's rather about using someone else's code. I'd prefer not to modify
> it, because otherwise I had to merge every update.

Gotcha. IMO, there is no need for the abstraction if it's limited to
these two functions.
You're only talking about a couple lines of code, and your need for
this won't expand much over time, it seems.

The helper is certainly useful though and I'd say if you wanted to use
eval to shorten it up, go for it, as long as it's not exposed to user
input.

If you've got a C compiler, the ruby-inline solution is likely safer.

That having been said, you don't want to create a Rube Goldberg machine. :)

-greg

Thomas Hafner

8/12/2007 11:16:00 PM

0

"Gregory Brown" <gregory.t.brown@gmail.com> wrote/schrieb <b37300880708121526j299f1ed3t3b7e45851d9ec0e9@mail.gmail.com>:

> Gotcha. IMO, there is no need for the abstraction if it's limited to
> these two functions.
> You're only talking about a couple lines of code, and your need for
> this won't expand much over time, it seems.

Nevertheless, if Ruby had explicit references (does it?), it would be
simple enough to have just one function instead of the original both
ones, e.g. with ``()'' as a placeholder for a hypothetical
dereferencing operator:

def with_stream_to_string(stream)
()stream, tmp = StringIO.new, ()stream
yield
()stream, tmp = tmp, ()stream
tmp.rewind
tmp.read
end

Regards
Thomas

Gregory Brown

8/13/2007 12:16:00 AM

0

On 8/12/07, Thomas Hafner <thomas@hafner.nl.eu.org> wrote:
> "Gregory Brown" <gregory.t.brown@gmail.com> wrote/schrieb <b37300880708121526j299f1ed3t3b7e45851d9ec0e9@mail.gmail.com>:
>
> > Gotcha. IMO, there is no need for the abstraction if it's limited to
> > these two functions.
> > You're only talking about a couple lines of code, and your need for
> > this won't expand much over time, it seems.
>
> Nevertheless, if Ruby had explicit references (does it?), it would be
> simple enough to have just one function instead of the original both
> ones

You'll want to catch up on this thread:
http://rubyu...

Basically, variables in ruby are just containers for references to
objects. So you can't change their bindings, which would be what
you'd need to do the kind of assignment you've shown there.