Need - macros feature

H

Henry Savr

Dear Ruby gurus:

Are there Ruby macro features as a part of Ruby standard?
I want them to work with ANY editor or interactive environment and with
ANY OS

Why?

Because it is distracting to key-in:

def a1
@a1
end
def a1=(value)
@a1=value
end

when you are thinking just about class' very general behaviour.
I would prefer to key-in something like this initially:

%def a1

and POSSIBLY add: -r, or -w, or -rw
on early design stage. Entering all the juzz above distracts strongly.
I'm going to work on details later.

Besides, I work on various systems and I want to have unified macro
options just by installing Ruby.

Thank you,
Henry
 
F

Farrel Lifson

Dear Ruby gurus:

Are there Ruby macro features as a part of Ruby standard?
I want them to work with ANY editor or interactive environment and with
ANY OS

Why?

Because it is distracting to key-in:

def a1
@a1
end
def a1=(value)
@a1=value
end

when you are thinking just about class' very general behaviour.
I would prefer to key-in something like this initially:

%def a1

and POSSIBLY add: -r, or -w, or -rw
on early design stage. Entering all the juzz above distracts strongly.
I'm going to work on details later.

Besides, I work on various systems and I want to have unified macro
options just by installing Ruby.

Thank you,
Henry

attr_accessor :a1 # RW
attr_reader :a1 # R
attr_writer :a1 # W

Farrel
 
H

Henry Savr

Farrel said:
attr_accessor :a1 # RW
attr_reader :a1 # R
attr_writer :a1 # W

Farrel
Thank you,
but my question was about MACRO option, so the preprocessor should work
and produce ruby source
 
P

Pierre Barbier de Reuille

Henry said:
Thank you,
but my question was about MACRO option, so the preprocessor should work
and produce ruby source
The good question is: what for ? In the case of the accessors, the
methods are define when the class is evaluated ... but when it is used,
there is no difference between accessors defined that way and accessors
defined the Hard Way (tm). The Good Thing (tm) with a dynamic language
as Ruby is you can safely generate your code (or parametrize it) so as
to avoid lot of typing, without any need for another macro-language, so
why not using this capability ?

Pierre
 
A

Austin Ziegler

Thank you,
but my question was about MACRO option, so the preprocessor should work
and produce ruby source

There is no preprocessor for Ruby.

Farrel's suggestion (metaprogramming with attr_accessor) is the right one.

-austin
 
E

Erik Veenstra

There is no preprocessor for Ruby.
Farrel's suggestion (metaprogramming with attr_accessor) is
the right one.

Yep, you're right. But he wants to know how to do it himself.
He wants to understand Why [1]... ;]

gegroet,
Erik V. - http://www.erikveen.dds.nl/

[1] http://whytheluckystiff.net/articles/seeingMetaclassesClearly.html

PS: Beer, downtown Amsterdam, tonight. No pancakes.

----------------------------------------------------------------

## Abstraction through meta-programming

## Getters and Setters - A Demo

# Consider this code:

class Foo
def bar
@bar
end

def bar=(new_bar)
@bar = new_bar
end
end

# This can be rewritten to this:

class Foo
def self.getter(iv)
define_method("#{iv}") do
instance_variable_get("@#{iv}")
end
end

def self.setter(iv)
define_method("#{iv}=") do |new_value|
instance_variable_set("@#{iv}", new_value)
end
end

getter :bar
setter :bar
end

# Which can be rewritten to this:

class Module
def getter(iv)
define_method("#{iv}") do
instance_variable_get("@#{iv}")
end
end

def setter(iv)
define_method("#{iv}=") do |new_value|
instance_variable_set("@#{iv}", new_value)
end
end
end

class Foo
getter :bar
setter :bar
end

# Which can be rewritten to this:

require "getter_and_setter.rb" # Fill it your self... ;]

class Foo
getter :bar
setter :bar
end

# Use it:

foo = Foo.new
foo.bar = "Hello World!"
puts foo.bar

----------------------------------------------------------------
 
J

John Carter

Are there Ruby macro features as a part of Ruby standard?
I want them to work with ANY editor or interactive environment and with
ANY OS

Ruby is it's own macro preprocessor and it is way way way smarter and
better than any other you have met. (Unless you have met Scheme hygienic
macros)

Say
ri eval
and
ri class_eval
and
ri instance_eval

The evils of eval can easily exceed the (relatively) minor sins of a
preprocessor and will eventually eat you.

John Carter Phone : (64)(3) 358 6639
Tait Electronics Fax : (64)(3) 359 4632
PO Box 1645 Christchurch Email : (e-mail address removed)
New Zealand

Carter's Clarification of Murphy's Law.

"Things only ever go right so that they may go more spectacularly wrong later."

From this principle, all of life and physics may be deduced.
 
H

Henry Savr

Thank you, guys
Although it's not what I wanted, I have a lot of ideas in some
directions. It's good for new in Ruby.
Henry
 
M

Matthew Johnson

Thank you, guys
Although it's not what I wanted, I have a lot of ideas in some
directions. It's good for new in Ruby.
Henry

Can you describe some of your ideas? That would certainly help
foster discussion...

Matthew
 
H

Henry Savr

Matthew said:
Can you describe some of your ideas? That would certainly help
foster discussion...

Matthew

Sure I will, but I am very short in time now. That was why I could not
be here earlier. Next week is for sure.
 
H

Henry Savr

Matthew said:
Can you describe some of your ideas? That would certainly help
foster discussion...

Matthew

There is nothiing new. It's as old as Univac
What I want is a classic Macroprocessor tool.
I mean:
I keep pieces of souce code in some place.
They may be included in source code as is. More interesting, you can
adjust macroprocessor's output (hence, the input for Ruby interpeter)
using paremters.

E X A M P L E:
===============
You wrote the macro once and put it in macro library
(here I "invented" the "macrolanguage" on-fly, while writing the
example. I hope, the "language" is clear)

====this is a macro %var with argument %%x definition==============
macro: %var (%%x)

{def %%x=(value)
@%%x = value
return @%%x
end}
======== end of macro %var definition =============================
You may consider the macro definition as a template.


Now, somewhere in your code you write:
...
%var(my_lovely_var)
...

Once found the %var, macroprocessor should make substitutions and
produce this piece:

def my_lovely_var=(value)
@my_lovely_var = value
return @my_lovely_var
end

which will be inserted into code on the place, where the statement
%var(my_lovely_var) was instead of it.



Ruby style allows to expect, that it may be done on-fly.

So, finally the Ruby interpreter will execute the macroprocessor's
output, not input. Besides the macroprocessor's input and output are
saved, so you can return to them and change the simple lines of
get/set-code to something more complicated and valueable.

Again the get/set operations are just an EXAMPLE, used because everyone
is familiar with this piece of code. Sure, using attributes is kind of
solution for this particular case. (BTW. Thank you, Farrel Lifson, you
post convinced me to learn more about attributes on this very beginning
stage, and that was very usefull). I want the macro power options
themselves.

Sure, every language may consider any code as an input string, and
process the string, (and Ruby itself is a great for these purposes), but
macroprocessor is something very specialized for swiftness and
convinience, to do particular job of entering the code. Ruby's
macroprocessor tool may be specialized for entering Ruby code, which
would make it more powerful.

There are plenty of editors with comprehensive macro functions. But they
are OS dependent. As Ruby is claimed to be system independent, I would
prefer to have Ruby's own macroprocessor, built for Ruby in mind.

More I am writing on this topic, more I am thinking, that a highly
customized for Ruby editor with macro functions would be the solution...
 
L

Logan Capaldo

There is nothiing new. It's as old as Univac
What I want is a classic Macroprocessor tool.
I mean:
I keep pieces of souce code in some place.
They may be included in source code as is. More interesting, you can
adjust macroprocessor's output (hence, the input for Ruby interpeter)
using paremters.

E X A M P L E:
===============
You wrote the macro once and put it in macro library
(here I "invented" the "macrolanguage" on-fly, while writing the
example. I hope, the "language" is clear)

====this is a macro %var with argument %%x definition==============
macro: %var (%%x)

{def %%x=(value)
@%%x = value
return @%%x
end}
======== end of macro %var definition =============================
You may consider the macro definition as a template.


Now, somewhere in your code you write:
...
%var(my_lovely_var)
...

Once found the %var, macroprocessor should make substitutions and
produce this piece:

def my_lovely_var=(value)
@my_lovely_var = value
return @my_lovely_var
end

which will be inserted into code on the place, where the statement
%var(my_lovely_var) was instead of it.



Ruby style allows to expect, that it may be done on-fly.

So, finally the Ruby interpreter will execute the macroprocessor's
output, not input. Besides the macroprocessor's input and output are
saved, so you can return to them and change the simple lines of
get/set-code to something more complicated and valueable.

Again the get/set operations are just an EXAMPLE, used because
everyone
is familiar with this piece of code. Sure, using attributes is kind of
solution for this particular case. (BTW. Thank you, Farrel Lifson, you
post convinced me to learn more about attributes on this very
beginning
stage, and that was very usefull). I want the macro power options
themselves.
I think maybe you underestimate what can be done with meta
programming in ruby that (almost) obviates the need for macros.

class Module
# "macro" definition
def var(symbol)
define_method("#{symbol}=") { |value| instance_variable_set("@#
{symbol}", value) }
end
end

class A
var :my_lovely_var
end
a = A.new
a.my_lovely_var = 1

Maybe if you can come up with a less trivial example, you can stump
us, but I doubt it.
 
P

Phil Tomson

I think maybe you underestimate what can be done with meta
programming in ruby that (almost) obviates the need for macros.

class Module
# "macro" definition
def var(symbol)
define_method("#{symbol}=") { |value| instance_variable_set("@#
{symbol}", value) }
end
end

class A
var :my_lovely_var
end
a = A.new
a.my_lovely_var = 1

Maybe if you can come up with a less trivial example, you can stump
us, but I doubt it.

While Ruby's metaprogramming facilities are indeed powerful, they
still don't allow you to change the syntax of the language as Lisp
macros allow. So, for example, if I wanted to define a new operator
:= for assignment semantics I can't do that with metaprogramming, but
if Ruby had Lisp-like macros it would be possible.


Phil
 
L

Logan Capaldo

While Ruby's metaprogramming facilities are indeed powerful, they
still don't allow you to change the syntax of the language as Lisp
macros allow. So, for example, if I wanted to define a new operator
:= for assignment semantics I can't do that with metaprogramming, but
if Ruby had Lisp-like macros it would be possible.


Phil

Yes I know, which is why I said (almost). OTOH Lisp macros letting
you change the syntax is sort of a red herring, since all lisp syntax
looks the same anyway ;-)
 
U

User Name

Henry Savr said:
<a desire for macros in ruby>

What about this? It's still a far cry from lisp macros, as it only
lets you define macros that work at the module level, and you need to
appropriately quote the input to a macro yourself, but I think with a
bit more reworking we could get "macros" to work at whatever level was
desired.

class Module
def defmacro(symbol, &block)
methodproc = Proc.new {|*a|self.class_eval(block.call(*a))}
self.send:)define_method, symbol, methodproc)
end

# Example macro that does what was mentioned in the long request:

defmacro:)var){|name,init|%Q{
def #{name}
@#{name} = #{init.inspect} unless defined? @#{name}
@#{name}
end
def #{name}=(val)
@#{name}=val
end
}}

# A silly macro - creates some number of attributes all
# with the same prefix, and initial values nil

defmacro:)varfamily){|name,n|
(1..n).map{|i|"var :#{name}_#{i}"}.join("\n")
}
end


Now let's test this out:

irb(main):033:0> class Foo; varfamily :foo,10; end
=> nil
irb(main):034:0> g = Foo.new
=> #<Foo:0x299b668>
irb(main):036:0> g.methods.select{|m|m=~/^foo/}.sort
=> ["foo_1", "foo_10", "foo_10=", "foo_1=", "foo_2", "foo_2=",
"foo_3", "foo_3=", "foo_4", "foo_4=", "foo_5", "foo_5=",
"foo_6", "foo_6=", "foo_7","foo_7=", "foo_8", "foo_8=",
"foo_9", "foo_9="]
irb(main):037:0> g.foo_5
=> nil
irb(main):038:0> g.foo_5=6
=> 6
irb(main):039:0> g.foo_5
=> 6

I still think that you're almost always better off using some already
present meta-programming tool, but if you really want a string-parsing
macro soup, this might do the trick.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,822
Latest member
israfaceZa

Latest Threads

Top