#define alternative for Ruby


#1

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


#2

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


#3

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/


#4

On Mar 12, 1:52 am, Daniel B. removed_email_address@domain.invalid 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.


#5

On 3/11/07, SonOfLilit removed_email_address@domain.invalid 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 Ruby
http://talklikeaduck.denhaven2.com/


#6

On Mar 12, 9:03 am, “Rick DeNatale” removed_email_address@domain.invalid 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.


#7

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.


#8

On 3/12/07, Timothy H. removed_email_address@domain.invalid 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.


#9

On 3/11/07, Michael S. removed_email_address@domain.invalid 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


#10

On 3/11/07, Alexey V. removed_email_address@domain.invalid wrote:

Try to implement it using standard techniques.

var ||= val

Although this will only work with @var


#11

On Mon, 12 Mar 2007, Michael S. 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


#12

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


#13

removed_email_address@domain.invalid 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.


#14

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


#15

On Mon, Mar 12, 2007 at 12:56:26PM +0900, Michael S. 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.


#16

On Mar 12, 4:07 pm, removed_email_address@domain.invalid 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?


#17

On Mar 12, 4:21 pm, removed_email_address@domain.invalid 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”


#18

On Mar 12, 7:16 pm, Sebastian H. removed_email_address@domain.invalid
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”


#19

On Mar 12, 7:47 pm, Brian C. removed_email_address@domain.invalid 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”


#20

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 :slight_smile:

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.