#define alternative for Ruby

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

Use the P4 preprocessor on your scripts :stuck_out_tongue: 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/

···

On 3/11/07, Michael Strelnikov <michaelst@gmail.com> 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.

Thanks,
Michael

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

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.

···

On 3/11/07, SonOfLilit <sonoflilit@gmail.com> wrote:

Use the P4 preprocessor on your scripts :stuck_out_tongue: 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.

--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

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.

···

On Mar 12, 1:52 am, Daniel Berger <djber...@gmail.com> wrote:

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

I agree there are some semantic problems. But there are huge
advantages as well.
I'd prefer for have some warning about redefinitions.

···

On Mar 12, 9:03 am, "Rick DeNatale" <rick.denat...@gmail.com> wrote:

On 3/11/07, SonOfLilit <sonofli...@gmail.com> wrote:

> Use the P4 preprocessor on your scripts :stuck_out_tongue: 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 Rubyhttp://talklikeaduck.denhaven2.com/

Mike wrote:

···

On Mar 12, 1:52 am, Daniel Berger <djber...@gmail.com> wrote:
  

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
    
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.

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

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

regards.

-a

···

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.

--
be kind whenever possible... it is always possible.
- the dalai lama

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.

···

On 3/12/07, Timothy Hunter <TimHunter@nc.rr.com> wrote:

Mike wrote:
> On Mar 12, 1:52 am, Daniel Berger <djber...@gmail.com> wrote:
>
>> 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
>>
>
> 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.

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.

···

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:

--
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"

···

On Mar 12, 4:21 pm, ara.t.how...@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:

     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
--
be kind whenever possible... it is always possible.
- the dalai lama

var ||= val

···

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.

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

     p var

     harp:~ > ruby a.rb
     42

-a

···

On Mon, 12 Mar 2007, Michael Strelnikov wrote:

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.

--
be kind whenever possible... it is always possible.
- the dalai lama

???

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

···

On Mon, Mar 12, 2007 at 05:16:08PM +0900, 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.

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.

···

On Mon, Mar 12, 2007 at 12:56:26PM +0900, Michael Strelnikov wrote:

>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.

Just try to implement:
set_default(var, val)
-- if variable "var" is not defined (not existed) then assign value
"val"

···

On Mar 12, 7:16 pm, Sebastian Hungerecker <sep...@googlemail.com> wrote:

ara.t.how...@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.

--
Ist so, weil ist so
Bleibt so, weil war so

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.

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

···

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.

--
be kind whenever possible... it is always possible.
- the dalai lama

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" )

Although this will only work with @var

···

On 3/11/07, Alexey Verkhovsky <alexey.verkhovsky@gmail.com> wrote:

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