Forum: Ruby #define alternative for Ruby

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
637f745e44c81f4830ba7dca35c800b4?d=identicon&s=25 Michael Strelnikov (Guest)
on 2007-03-11 10:58
(Received via mailing list)
Hello all,

   Does Ruby have something like "#define" for C/C++? Especially with
arguments like "#define foo(x) (something_done_with_x(x))".

   Please don't say that "def" do the same. It doesn't.

Thanks,
Michael
7b4707f974af261f71943e1f2046c9ee?d=identicon&s=25 SonOfLilit (Guest)
on 2007-03-11 11:51
(Received via mailing list)
Use the P4 preprocessor on your scripts :P You'll get #define EXACTLY.

No, but seriously - text substitute macros are awful. There's a good
reason that Matz didn't offer them in Ruby.

If you want real macros, there's a sort of a way to do it with
ParseTree, but it's kind of complicated AFAIK (never tried).

Tell us what you want to do and we'll probably find a way to do it
without the awful #define.


Aur


Check http://rubymentor.rubyforge.org/
Aee77dba395ece0a04c688b05b07cd63?d=identicon&s=25 Daniel Berger (Guest)
on 2007-03-11 15:52
(Received via mailing list)
Michael Strelnikov wrote:
> Hello all,
>
>   Does Ruby have something like "#define" for C/C++? Especially with
> arguments like "#define foo(x) (something_done_with_x(x))".
>
>   Please don't say that "def" do the same. It doesn't.

The closest analogue is to conditionally define a constant, then used
defined? on that constant.

For example, I do something like this in the windows-pr project, where
some methods are not supported by Win2k or earlier:

module Windows
   module Console
     begin
       AttachConsole = Win32API.new('kernel32','AttachConsole','L', 'I')
     rescue LoadError
       # Requires Windows XP or later
     end
   end
end

And then, while using the above module:

class MyConsoleClass
    include Windows::Console

    def test
       if defined? AttachConsole
          # do something
       else
          # do something else
       end
    end
end

Regards,

Dan
8f6f95c4bd64d5f10dfddfdcd03c19d6?d=identicon&s=25 Rick Denatale (rdenatale)
on 2007-03-11 23:04
(Received via mailing list)
On 3/11/07, SonOfLilit <sonoflilit@gmail.com> wrote:
> Use the P4 preprocessor on your scripts :P You'll get #define EXACTLY.
>
> No, but seriously - text substitute macros are awful. There's a good
> reason that Matz didn't offer them in Ruby.

There's also the interesting problem of what the semantics of changing
 a text macro in a dynamically compiled language like ruby.  Let's say
you use a macro expansion in a method, and then later change the
macro. Do the methods which use that macro then need to be
re-compiled?  What if you introduce a new macro that has the same name
as a non-macro name.

--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/
637f745e44c81f4830ba7dca35c800b4?d=identicon&s=25 Mike (Guest)
on 2007-03-12 01:51
(Received via mailing list)
On Mar 12, 1:52 am, Daniel Berger <djber...@gmail.com> wrote:
>
>    end
>        else
>           # do something else
>        end
>     end
> end
>
> Regards,
>
> Dan

I was talking more about macros rather then constants.
But I agree that constant are convenient way to substitute "#define
myconst 15". But can you substitute "#define myfunc(x)
(sin(x)*cos(x)*exp(x))"?
You should know that "x" could be as much other functions as a
constant/variable.
637f745e44c81f4830ba7dca35c800b4?d=identicon&s=25 Mike (Guest)
on 2007-03-12 01:55
(Received via mailing list)
On Mar 12, 9:03 am, "Rick DeNatale" <rick.denat...@gmail.com> wrote:
> macro. Do the methods which use that macro then need to be
> re-compiled?  What if you introduce a new macro that has the same name
> as a non-macro name.
>
> --
> Rick DeNatale
>
> My blog on Rubyhttp://talklikeaduck.denhaven2.com/

I agree there are some semantic problems. But there are huge
advantages as well.
I'd prefer for have some warning about redefinitions.
3afd3e5e05dc9310c89aa5762cc8dd1d?d=identicon&s=25 Timothy Hunter (Guest)
on 2007-03-12 03:03
(Received via mailing list)
Mike wrote:
>>>
>>      rescue LoadError
>>     def test
>> Dan
>>
>
> I was talking more about macros rather then constants.
> But I agree that constant are convenient way to substitute "#define
> myconst 15". But can you substitute "#define myfunc(x)
> (sin(x)*cos(x)*exp(x))"?
> You should know that "x" could be as much other functions as a
> constant/variable.
>

I would be interested in hearing what you want to do with text
substitution that you cannot already do with standard Ruby
metaprogramming techniques.
637f745e44c81f4830ba7dca35c800b4?d=identicon&s=25 Michael Strelnikov (Guest)
on 2007-03-12 04:57
(Received via mailing list)
On 3/12/07, Timothy Hunter <TimHunter@nc.rr.com> wrote:
> >>>
> >>      begin
> >> class MyConsoleClass
> >>
> > constant/variable.
> >
>
> I would be interested in hearing what you want to do with text
> substitution that you cannot already do with standard Ruby
> metaprogramming techniques.
>
>
Easy.
Let's we have following function:
* set_default(var, val)
-- if variable "var" is not defined (not existed) then assign value
"val"
else do nothing.

The variable could be ANY type including "Fixnum".

Try to implement it using standard techniques.
38a02bf7121a81be5be6f3d488ce23b5?d=identicon&s=25 Alexey Verkhovsky (Guest)
on 2007-03-12 05:17
(Received via mailing list)
On 3/11/07, Michael Strelnikov <michaelst@gmail.com> wrote:
>
> Let's we have following function:
> * set_default(var, val)
> -- if variable "var" is not defined (not existed) then assign value "val"
> else do nothing.
>
> The variable could be ANY type including "Fixnum".
>
> Try to implement it using standard techniques.
>

var ||= val
38a02bf7121a81be5be6f3d488ce23b5?d=identicon&s=25 Alexey Verkhovsky (Guest)
on 2007-03-12 05:18
(Received via mailing list)
On 3/11/07, Alexey Verkhovsky <alexey.verkhovsky@gmail.com> wrote:
> >
> > Try to implement it using standard techniques.
> >
>
> var ||= val
>


Although this will only work with @var
Cb48ca5059faf7409a5ab3745a964696?d=identicon&s=25 unknown (Guest)
on 2007-03-12 06:08
(Received via mailing list)
On Mon, 12 Mar 2007, Michael Strelnikov wrote:

> The variable could be ANY type including "Fixnum".
>
> Try to implement it using standard techniques.

     harp:~ > cat a.rb
     unless defined? var
       var = 42
     end

     p var


     harp:~ > ruby a.rb
     42


-a
Cb48ca5059faf7409a5ab3745a964696?d=identicon&s=25 unknown (Guest)
on 2007-03-12 06:21
(Received via mailing list)
On Mon, 12 Mar 2007, Mike wrote:

>
> I was talking more about macros rather then constants.  But I agree that
> constant are convenient way to substitute "#define myconst 15". But can you
> substitute "#define myfunc(x) (sin(x)*cos(x)*exp(x))"?  You should know that
> "x" could be as much other functions as a constant/variable.
>

perhaps i'm being dense, but i fail to see how the above example is none
other
than a simple function in ruby:

     harp:~ > cat a.rb
     def myfunc x
       Math.sin(x) * Math.cos(x) * Math.exp(x)
     end

     # x as function
     def x() 42 end
     p myfunc(x)

     # x as constant
     X = 42
     p myfunc(X)

     # x as variable
     x = 42
     p myfunc(x)


     harp:~ > ruby a.rb
     6.37609775534436e+17
     6.37609775534436e+17
     6.37609775534436e+17

text macros like the above are really only useful in static/strong typed
languages.  in ruby, they are rather meaningless.

regards.

-a
7a561ec0875fcbbe3066ea8fe288ec77?d=identicon&s=25 Sebastian Hungerecker (Guest)
on 2007-03-12 09:16
(Received via mailing list)
ara.t.howard@noaa.gov wrote:
> On Mon, 12 Mar 2007, Mike wrote:
> > I was talking more about macros rather then constants.  But I agree that
> > constant are convenient way to substitute "#define myconst 15". But can
> > you substitute "#define myfunc(x) (sin(x)*cos(x)*exp(x))"?  You should
> > know that "x" could be as much other functions as a constant/variable.
>
> perhaps i'm being dense, but i fail to see how the above example is none
> other than a simple function in ruby:

Imagine you would call the function with rand() as parameter. With
#define
rand would be called three times, with def it would be called once and
its
value would be used three times.
753dcb78b3a3651127665da4bed3c782?d=identicon&s=25 Brian Candler (Guest)
on 2007-03-12 09:47
(Received via mailing list)
On Mon, Mar 12, 2007 at 05:16:08PM +0900, Sebastian Hungerecker wrote:
> Imagine you would call the function with rand() as parameter. With #define
> rand would be called three times, with def it would be called once and its
> value would be used three times.

???

irb(main):001:0> def myfunc(x); Math.sin(x)*Math.cos(x)*Math.exp(x); end
=> nil
irb(main):002:0> p myfunc(rand)
0.44720293351854
=> nil
irb(main):003:0> p myfunc(rand)
1.07121692170638
=> nil
irb(main):004:0> p myfunc(rand)
1.01827292445777
=> nil

Now, if you *store* the value of rand within the function, that's a
different case. But Ruby has different idioms for deferred execution:
one of
those is

class Foo
  def initialize(&blk)
    @gen = blk
  end
  def value
    @gen.call
  end
end

a = Foo.new { rand }
puts a.value
puts a.value
puts a.value
753dcb78b3a3651127665da4bed3c782?d=identicon&s=25 Brian Candler (Guest)
on 2007-03-12 09:53
(Received via mailing list)
On Mon, Mar 12, 2007 at 12:56:26PM +0900, Michael Strelnikov wrote:
>
> The variable could be ANY type including "Fixnum".
>
> Try to implement it using standard techniques.

Do you really need to abstract out "var ||= val" into its own function?

If for some reason you do, then local variables are not the right
abstraction. Local variables are statically created when code is parsed
(*);
local variables are not objects; and you cannot take references to them.

Use instance variables on an object instead.

Regards,

Brian.

(*) which means you can create them using "eval", but I'm pretty sure
you
don't want to do that.
637f745e44c81f4830ba7dca35c800b4?d=identicon&s=25 Mike (Guest)
on 2007-03-12 10:01
(Received via mailing list)
On Mar 12, 4:21 pm, ara.t.how...@noaa.gov wrote:
>      harp:~ > cat a.rb
>      p myfunc(X)
> text macros like the above are really only useful in static/strong typed
> languages.  in ruby, they are rather meaningless.
>
> regards.
>
> -a
> --
> be kind whenever possible... it is always possible.
> - the dalai lama

Just try to implement:
set_default(var, val)
-- if variable "var" is not defined (not existed) then assign value
"val"
637f745e44c81f4830ba7dca35c800b4?d=identicon&s=25 Mike (Guest)
on 2007-03-12 10:01
(Received via mailing list)
On Mar 12, 4:07 pm, ara.t.how...@noaa.gov wrote:
> > The variable could be ANY type including "Fixnum".
>      harp:~ > ruby a.rb
>      42
>
> -a
> --
> be kind whenever possible... it is always possible.
> - the dalai lama

I know it but imagine you must do it 100 times?
I'd rather write:
set_default(var1, 15)
set_default(myvar1, "string")
...
set_default(lastvar, myhash)

In your case I must use "var" twice. Don't you think it is too much?
637f745e44c81f4830ba7dca35c800b4?d=identicon&s=25 Mike (Guest)
on 2007-03-12 10:05
(Received via mailing list)
On Mar 12, 7:47 pm, Brian Candler <B.Cand...@pobox.com> wrote:
>
> => nil
>
> puts a.value
> puts a.value
> puts a.value

Just try to implement:
set_default(var, val)
-- if variable "var" is not defined (not existed) then assign value
"val"
637f745e44c81f4830ba7dca35c800b4?d=identicon&s=25 Mike (Guest)
on 2007-03-12 10:05
(Received via mailing list)
On Mar 12, 7:16 pm, Sebastian Hungerecker <sep...@googlemail.com>
wrote:
> Imagine you would call the function with rand() as parameter. With #define
> rand would be called three times, with def it would be called once and its
> value would be used three times.
>
> --
> Ist so, weil ist so
> Bleibt so, weil war so

Just try to implement:
set_default(var, val)
-- if variable "var" is not defined (not existed) then assign value
"val"
753dcb78b3a3651127665da4bed3c782?d=identicon&s=25 Brian Candler (Guest)
on 2007-03-12 10:22
(Received via mailing list)
On Mon, Mar 12, 2007 at 06:05:25PM +0900, Mike wrote:
> > irb(main):003:0> p myfunc(rand)
> > class Foo
> > puts a.value
> > puts a.value
>
> Just try to implement:
> set_default(var, val)
> -- if variable "var" is not defined (not existed) then assign value
> "val"

I think we have a stuck record here :-)

For this particular example, the code you are looking for is:

  var ||= val

with no method call at all. This is a tiny pattern and not worth
abstracting.

Local variables are *static*. Local variables are not intended to be
handled
in the way you are asking. The language provides other facilities (i.e.
not
local variables) when you want to be more dynamic.

"Doctor, it hurts when I do this."
"Then don't do that!"

Try the following if you don't understand what I mean by local variables
being "static".

  def x
    "This method is never called"
  end

  if false
    x = "Local variable"
  end

  puts x

This code prints "nil". Reflect on why this is the case.

Regards,

Brian.
637f745e44c81f4830ba7dca35c800b4?d=identicon&s=25 Michael Strelnikov (Guest)
on 2007-03-12 10:32
(Received via mailing list)
On 3/12/07, Brian Candler <B.Candler@pobox.com> wrote:
> > > => nil
> > > Now, if you *store* the value of rand within the function, that's a
> > >   end
> > "val"
> Local variables are *static*. Local variables are not intended to be
>
> This code prints "nil". Reflect on why this is the case.
>
> Regards,
>
> Brian.
>
>
The "local variables" is exactly what confuses me.  Why can't I use
variables (read/set) inside of function that is at the same hierarchy as
variable is?
753dcb78b3a3651127665da4bed3c782?d=identicon&s=25 Brian Candler (Guest)
on 2007-03-12 10:45
(Received via mailing list)
On Mon, Mar 12, 2007 at 06:00:21PM +0900, Mike wrote:
> I know it but imagine you must do it 100 times?
> I'd rather write:
> set_default(var1, 15)
> set_default(myvar1, "string")
> ...
> set_default(lastvar, myhash)

OK, if you *really* insist:

---- 8< -------------------------------------------------
require 'rubygems'
require 'active_support/binding_of_caller'

def set_default(var, val)
  Binding.of_caller do |binding|
    eval("#{var} ||= #{val}", binding)
  end
end

var1 = nil                  # <<<<<<< A
set_default("var1", 5)
set_default("var1", 15)
puts var1                   # <<<<<<< B    (prints 5)
---- 8< -------------------------------------------------

This works as written; but you'll find you get bitten by the static
nature
of local variables if you remove line "A". It then fails.

This is because of the ambiguity in line B: "puts var1" could be
referring
to a method call - puts self.var1() - or a local variable. This
ambiguity is
resolved at *parse* time, before any code has been executed at all,
simply
based on whether a statement of the form "var1 = xxx" has been seen
earlier
in the file.

If you remove line A, then line B is already resolved as puts
self.var1()
*before* any code has been executed.

Now, macros would be fine here - but only if these macros were expanded
at
parse time. That makes them very static, and not very useful in a
dynamic
language like Ruby.

As others have said before: provide a *real* example of where you would
need
macros, not a noddy "var ||= val" replacement, and we'll show you how
Rubyists would handle this case.

Regards,

Brian.
753dcb78b3a3651127665da4bed3c782?d=identicon&s=25 Brian Candler (Guest)
on 2007-03-12 11:15
(Received via mailing list)
On Mon, Mar 12, 2007 at 06:31:02PM +0900, Michael Strelnikov wrote:
> The "local variables" is exactly what confuses me.  Why can't I use
> variables (read/set) inside of function that is at the same hierarchy as
> variable is?

Because each 'def' starts a brand new scope for local variables, and
local
variables outside that scope are not visible.

Doing this has several advantages:

(1) Much more efficient to implement.

- When you refer to a local variable "x" it can only be within your own
stack frame, at a known offset; no need to hunt outside.

- It enables the parse-time decision as to whether "x" is a local
variable
or method call. Otherwise this decision could only be made a run-time,
and
performance would suck even for simple statements like "x = y"

(2) Makes it much harder to introduce unforeseen side effects by
affecting
local variables outside of the method you are defining.

So, you may be used to writing something like

  x = ...

  def myfunc(a)
    .. stuff which uses x and a
  end

in another language, but if so you'll need to think slightly differently
in
Ruby.

When you define "functions" at the "top level" of your program, you are
really defining methods inside an object called 'main'. As soon as you
introduce your own objects, these problems tend to vanish, because
instance
variables are the de-rigeur:

class Myclass
  def initialize(x)
    @x = x
  end

  def myfunc(a)
    .. stuff which uses @x and a
  end
end

All but the most trivial of Ruby programs declare classes like this. And
there are plenty of ways of doing reflection on methods and instance
variables. The simplest example is

class Myclass
  attr_accessor :foo
end

which creates methods equivalent to the following:

class Myclass
  def foo=(val)
    @foo = val
  end
  def foo
    @foo
  end
end

You can write your own analogue to attr_accessor which also sets a
default
value for an attribute, should you so wish, although this is usually
done
inside the 'initialize' method of your class. An if you're making
objects
with lots of attributes which vary at runtime, you'd probably be better
off
looking at Struct or OpenStruct as a starting point.

Regards,

Brian.
703fbc991fd63e0e1db54dca9ea31b53?d=identicon&s=25 Robert Dober (Guest)
on 2007-03-12 11:45
(Received via mailing list)
On 3/12/07, Brian Candler <B.Candler@pobox.com> wrote:
> > > => nil
> > >
> > > puts a.value
> For this particular example, the code you are looking for is:
>
>   var ||= val
Please note that
    var ||= val
is not the same than
   var = val unless defined? var

Very often it is preferable of course.
Robert

<snip>
3afd3e5e05dc9310c89aa5762cc8dd1d?d=identicon&s=25 Timothy Hunter (Guest)
on 2007-03-12 12:41
(Received via mailing list)
Mike wrote:
> Just try to implement:
> set_default(var, val)
> -- if variable "var" is not defined (not existed) then assign value
> "val"
>

I'd like to point out that you can't do that with #define, since C
macros are processed before the compiler runs, and whether or not "var"
is defined is not known until the compiler runs.
753dcb78b3a3651127665da4bed3c782?d=identicon&s=25 Brian Candler (Guest)
on 2007-03-12 13:22
(Received via mailing list)
On Mon, Mar 12, 2007 at 07:44:49PM +0900, Robert Dober wrote:
> >For this particular example, the code you are looking for is:
> >
> >  var ||= val
> Please note that
>    var ||= val
> is not the same than
>   var = val unless defined? var
>
> Very often it is preferable of course.

Indeed - it will set values when var == nil or var == false as well.

However, calling a run-time 'defined?' method is usually redundant,
since in
almost all cases you can tell statically whether it's defined or not:

    if false
      var = 123
    end
    puts defined? var    # redundant, var is *always* defined here

But in some cases you might want

   var = val if var.nil?

(e.g. if you are dealing with a boolean variable)
703fbc991fd63e0e1db54dca9ea31b53?d=identicon&s=25 Robert Dober (Guest)
on 2007-03-12 13:42
(Received via mailing list)
On 3/12/07, Timothy Hunter <TimHunter@nc.rr.com> wrote:
>
>
Although I am against macros it might be worth pointing out that of
course it can be done

#define MYDEFINE var val \
 var = val unless defined? var

forgive me if the syntax is incorrect.
The Ruby interpreter will not see the macro and vice versa.

BTW on Linux I guess you can always use gcc to preprocess files anyway,
but
STAY AWAY FROM THIS.

Sorry for shouting, but I wanted to be heared ;)
Cheers
Robert
B33ea5c12d767bfd1253940a960274f5?d=identicon&s=25 Tim Hunter (timhunter)
on 2007-03-12 13:52
Robert Dober wrote:
> On 3/12/07, Timothy Hunter <TimHunter@nc.rr.com> wrote:
>>
>>
> Although I am against macros it might be worth pointing out that of
> course it can be done
>
> #define MYDEFINE var val \
>  var = val unless defined? var
>
> forgive me if the syntax is incorrect.
> The Ruby interpreter will not see the macro and vice versa.
>
> BTW on Linux I guess you can always use gcc to preprocess files anyway,
> but
> STAY AWAY FROM THIS.
>
> Sorry for shouting, but I wanted to be heared ;)
> Cheers
> Robert

Perhaps we are discussing different kinds of variables. Your macro tests
if a given preprocessor symbol is defined or not. Such a symbol must be
defined (or not) when the preprocessor runs. Probably the closest analog
in Ruby is a global constant. I was talking about variables such as
automatics or statics, much closer to Ruby's variables.
Cb48ca5059faf7409a5ab3745a964696?d=identicon&s=25 unknown (Guest)
on 2007-03-12 15:52
(Received via mailing list)
On Mon, 12 Mar 2007, Sebastian Hungerecker wrote:

> ara.t.howard@noaa.gov wrote:
>> On Mon, 12 Mar 2007, Mike wrote:
>>> I was talking more about macros rather then constants.  But I agree that
>>> constant are convenient way to substitute "#define myconst 15". But can
>>> you substitute "#define myfunc(x) (sin(x)*cos(x)*exp(x))"?  You should
>>> know that "x" could be as much other functions as a constant/variable.
>>
>> perhaps i'm being dense, but i fail to see how the above example is none
>> other than a simple function in ruby:
>

> Imagine you would call the function with rand() as parameter. With #define
> rand would be called three times, with def it would be called once and its
> value would be used three times.

absolutely.  but that's generally considered a problem with macros, not
a
feature.  besides, that's easy too

   harp:~ > cat a.rb
   def myfunc *a, &b
     x = a.shift || b.call
     Math.sin(x) * Math.cos(x) * Math.exp(x)
   end

   # x as function
   def x() 42 end
   p myfunc(x)

   # x as constant
   X = 42
   p myfunc(X)

   # x as variable
   x = 42
   p myfunc(x)

   # x as rand
   p myfunc{ rand }


regards.


-a
703fbc991fd63e0e1db54dca9ea31b53?d=identicon&s=25 Robert Dober (Guest)
on 2007-03-12 16:17
(Received via mailing list)
On 3/12/07, Tim Hunter <rmagick@gmail.com> wrote:
> > forgive me if the syntax is incorrect.
> Perhaps we are discussing different kinds of variables. Your macro tests
> if a given preprocessor symbol is defined or not. Such a symbol must be
> defined (or not) when the preprocessor runs. Probably the closest analog
> in Ruby is a global constant. I was talking about variables such as
> automatics or statics, much closer to Ruby's variables.

Sorry I was focused on the original idea, I understand your remark now,
thx for clarifying.
Robert
Cb48ca5059faf7409a5ab3745a964696?d=identicon&s=25 unknown (Guest)
on 2007-03-12 16:24
(Received via mailing list)
On Mon, 12 Mar 2007, Mike wrote:

> I know it but imagine you must do it 100 times?
> I'd rather write:
> set_default(var1, 15)
> set_default(myvar1, "string")
> ...
> set_default(lastvar, myhash)
>
> In your case I must use "var" twice. Don't you think it is too much?

in that case i'd probably just use

   var1 ||= 15

or instance variables.  there a so many ways to skin that cat.  you
could do
something subversive like this if yoiu really wanted to

   harp:~ > cat a.rb
   require 'binding_of_caller'

   def set_default a, &b
     @set_default = b
     Binding.of_caller do |binding|
       eval "
         class << self
           define_method '#{ a }', &@set_default
         end
       ", binding
     end
   end

   100.times{|i| set_default(:x){ i + 1 } }

   p x #=> 100

i guess i see that there are times when a macro might make things faster
to
write, but the tradeoff, as we all know, it that they are then slower to
debug.  in the end you cannot do anything you coulnd't without one and
it can
substantially confuse debugging when text substitution, dynamic scoping,
and
closures are mixed.  consider

   later = Queue.new

   #define now( x ) later.push(lambda{ x })


   x = 40
   now(x += 2)

   p x #=> 40

   sleep rand

   p x #=> 42

regards.

-a
E34b5cae57e0dd170114dba444e37852?d=identicon&s=25 Logan Capaldo (Guest)
on 2007-03-23 00:51
(Received via mailing list)
> set_default(var, val)
> -- if variable "var" is not defined (not existed) then assign value
> "val"
>
require 'binding_of_caller' # google for this, you need call_stack
                            # or equiv for ruby >= 1.8.5
def set_default( var, val )
  Binding.of_caller do |b|
    eval("#{var} = #{val} unless #{var}", b)
  end
end

set_default( "a", "7" )
1c1e3bdfe006a22214102fcd6434a012?d=identicon&s=25 Daniel Sheppard (Guest)
on 2007-03-23 02:27
(Received via mailing list)
>    harp:~ > cat a.rb
>    def myfunc *a, &b
>      x = a.shift || b.call
>      Math.sin(x) * Math.cos(x) * Math.exp(x)
>    end

That's got the same problem - rand will only be evaluated once, what you
were no doubt after is:

def myfunc *a, &b
  b ||= proc { a.first }
  Math.sin(b.call) * Math.cos(b.call) * Math.exp(b.call)
end

But the point remains, anything macros do, functions or metaprogramming
do better.

Dan.
This topic is locked and can not be replied to.