[#1649] Re: New Ruby projects — Yukihiro Matsumoto <matz@...>
The following message is a courtesy copy of an article
[#1672] Re: Ruby 1.4 stable manual bug? — Yukihiro Matsumoto <matz@...>
The following message is a courtesy copy of an article
[#1673] Re: Possible problem with ext/socket in 1.5.2 — itojun@...
[#1694] Conventions for our Ruby book — Dave Thomas <Dave@...>
[#1715] Install postgresql support — Ikhlasul Amal <amal@...>
Hi all,
Hi,
[#1786] Is this a bug? — Clemens Hintze <clemens.hintze@...>
(mailed & posted)
[#1814] Objects nested sometimes. — Hugh Sasse Staff Elec Eng <hgs@...>
I am attemptiong to write a package which consists of a workspace
[#1816] Ruby 1.5.3 under Tru64 (Alpha)? — Clemens Hintze <clemens.hintze@...>
Hi all,
Hi,
Yukihiro Matsumoto writes:
Hi,
Hi,
[#1834] enum examples? — Hugh Sasse Staff Elec Eng <hgs@...>
Has anyone any examplse of using the Enumerable module? I've had a
[#1844] Minor irritation, can't figure out how to patch it though! — Hugh Sasse Staff Elec Eng <hgs@...>
I was considering how difficult it would be to patch Ruby to accept
[#1889] [ruby-1.5.3] require / SAFE — ts <decoux@...>
[#1896] Ruby Syntax similar to other languages? — "David Douthitt" <DDouthitt@...>
From: Yukihiro Matsumoto <matz@netlab.co.jp>
[#1900] Enumerations and all that. — Hugh Sasse Staff Elec Eng <hgs@...>
Thank you to the people who responded to my questions about Enumerated
Hugh Sasse Staff Elec Eng <hgs@dmu.ac.uk> writes:
On 16 Mar 2000, Dave Thomas wrote:
[#1929] Re: Class Variables — "David Douthitt" <DDouthitt@...>
| "David Douthitt" <DDouthitt@cuna.com> writes:
[#1942] no Fixnum#new ? — Quinn Dunkan <quinn@...>
Ok, I can add methods to a built-in class well enough (yes I know about succ,
[#1989] English Ruby/Gtk Tutorial? — schneik@...
Hi,
[#2022] rb_global_entry — ts <decoux@...>
[#2036] Anonymous and Singleton Classes — B_DAVISON <Bob.Davison@...>
I am a Ruby newbie and having some problems getting my mind around certain
[#2069] Ruby/GTK+ question about imlib --> gdk-pixbug — schneik@...
[#2073] Re: eval.rb fails — "Dat Nguyen" <thucdat@...>
The doc is fine, this happens only if you try to execute 'until' block
On Wed, 22 Mar 2000, Dat Nguyen wrote:
[#2084] Scope violated by import via 'require'? — Clemens Hintze <c.hintze@...>
Hi,
[#2104] ARGF or $< — Hugh Sasse Staff Elec Eng <hgs@...>
Has anyone any examples of how to use ARGF or $< as I cannot find much
Hi.
[#2165] Ruby strict mode and stand-alone executables. — "Conrad Schneiker" <schneiker@...>
Some people want Ruby to have a strict compile mode.
[#2203] Re: parse bug in 1.5 — schneik@...
[#2212] Re: Ruby/Glade usage questions. — ts <decoux@...>
>>>>> "m" == mrilu <mrilu@ale.cx> writes:
[#2241] setter() for local variables — ts <decoux@...>
[#2256] Multiple assignment of pattern match results. — schneik@...
[#2267] Re: Ruby and Eiffel — h.fulton@...
[#2309] Question about attribute writers — Dave Thomas <Dave@...>
Clemens Hintze <c.hintze@gmx.net> writes:
[ruby-talk:02058] Lockfiles
David Douthitt writes:
> | >>> Clemens Hintze <c.hintze@gmx.net> 03/20/00 11:08PM >>>
...
> | Perhaps it is what you have searched?
> |
> | But then, nobody has told me if you like to re-invent the wheel again
> | ;-)
>
> Only sometimes :-)
And here you have found the *great* danger of Ruby... because
programming in Ruby is so fun, and beause Ruby makes it really easy to
re-invent the wheel again and again, I often do it! ;-)
Instead of using smart code snippets from other, I really like to
write them myself. Not every time, but if I am bored, for example. I
never had that feeling with other languages... :-)
> Yet, I don't think your script is what I had in mind. I'm not looking
> to "lock a file" - but to create a UNIX-style lockfile in
> (typical example) /var/spool/locks/ - as it is under HP-UX 10.20 here.
> This looks like your class LockFile but your code seems quite complex.
> I'm not sure that all that is what I needed. My class Lock turned out
> to be much simpler I think.
If you only want to synchronize your own apps, you do not need the
whole complexity from my filelock.rb. But if you wants to work
together with the e.g. system mailbox, things are more complicate
then. Then you would also have to check if lockfile was stolen and
such things.
>
> That first line is a marvel! "/bin/env ruby" ... hmmm!
You do not like it? ;-) I use it anytime! The program 'env' is used
for two purposes.
1. Displaying of all environment variable (called without parameter)
2. Start a program with some environment variables set to a certain
value *only* for that process.
The 2nd point is funny! Suppose you have your DISPLAY variable set to
qiao:0, but you will display an xterm on didi:0, you can do this:
env DISPLAY=didi:0 xterm -title "Yuhu2" &
And now, *only* for the xterm process DISPLAY was set to another
value. The nice side effect is, that the program 'env' will search for
the executable to be executed in your PATH. So '/bin/env ruby' means:
search the program ruby in along PATH. If found start it. So my
scripts becomes location independend from the Ruby interpreter.
Unfortunately the 'env' programm can be found sometimes in '/bin'
sometimes in '/usr/bin'. But there are much more locations possible
for Ruby. At home I have a link from '/usr/bin/env' -->
'/bin/env'. That makes me really independend! :-)))
But now coming to your script... May I propose some changings?
Proposing them does not mean your solution is wrong, however!
> Here's my code:
>
> #!/opt/ruby/bin/ruby
>
> class Lock
> attr_accessor :locked_up, :lockdir, :lockfile
>
> def initialize (lockf = nil)
> @locked_up = false
> @lockdir = "/var/spool/locks"
Although Ruby does not really need it because it handles '/' as
separator all the time, I think it would be better to use File::join
to do the job:
@lockdir = File::Separator + File.join(%w(var spool locks))
> if (lockf == nil)
> @lockfile = (@lockdir + "/" + File.basename($0) + ".lock")
Here too...
!!! @lockfile = File.join(@lockdir, File.basename($0)) + ".lock"
> else
> @lockfile = (@lockdir + "/" + lockf + ".lock")
And here
!!! @lockfile = File.join(@lockdir, lockf) + ".lock"
> end
> end
>
> def setlock (lockf = @lockfile)
> raise "Lockfile not set!" if lockf == nil;
> raise "Lock failed!" if
> ! system("set -o noclobber ; cat /dev/null 2> /dev/null > #{lockf}")
Why do you use such complicate system call here? I would prefer a Ruby
solution:
if not File.exist?(lockf)
begin File.open(lockf, "w") { |fp| fp.write(Process.pid) }
rescue
raise "Lock failed (system error)"
end
else
raise "Lock failed (already locked)"
end
Is a little bit longer but portable and deliver two different
exceptions depending on the error occured. Okay not different
exceptions but different explanations ;-)
>
> at_exit { self.unlock }
> @locked_up = true
> end
>
> def locked?
> test(?e, @lockfile)
Is ok! But I find the following more self descriptive...
!!! File.exist? @lockfile
> end
>
> def Lock.locked? (lockf)
> test(?e, "/var/spool/locks/" + lockf)
Same as above...
!!! File.exist?(File::Separator + File.join(%w(var spool locks)) + lockf
> end
>
> def locked
> self.setlock
> yield
> self.unlock
> end
>
> def unlock
> test(?e, @lockfile) if
> raise "Unlock failed!" if
> ! system("rm -f #{@lockfile}");
What you are try to doing here? If 'rm -f' failed the exception is
raised and 'test(?e,...)' will not performed. If 'rm' went well,
neither 'raise' nor 'test' will be executed.
raise "Unlock failed (no lock)" unless File.exist?(@lockfile)
begin
File.delete @lockfile
rescue
raise "Unlock failed (couldn't remove lockfile)"
end
>
> @locked_up = false
> end
> end
>
> >>> I use it this way:
>
> mylock = Lock.new
>
> mylock.locked {
> # ....do stuff....
> }
>
> >>> or this way:
>
> return if Lock.locked?("Oracle.lock")
>
> >>>
>
> What do you think?
Your code is ok! Only there are some things I would like to
remark.
1. You often use constants like "/var/spool/locks" throughout your
whole code.
2. You use too much system dependend things like system(...)
here. This it not really necessary.
3. You should not use things like 'test(?e, ...)'. The Ruby classes
are more descriptive.
4. IMHO, your code is not carefully designed for the class/instance
clash. Means, you do some things both in class methods and in
instance methods.
5. You should not on any case define accessors for your class. I
would consider it not-so-good style if I would have to:
lock = Lock.new("/var/spool/mail/cle")
lock.lockdir = "/var/spool/mail"
lock.setlock
following would be better, IMO:
lock = Lock.new("/var/spool/mail/cle", "/var/spool/mail")
lock.setlock
All in all I would say, that your code may be appropiate for what you
have in mind for your apps. But it is not generic enough, IMHO! No
steal-the-lock feature. No wait for the lock. No auto-unlock as soon
as I do not need this file instance anymore...
But keep fun, ok? :-)
\cle
--
Clemens Hintze mailto: c.hintze@gmx.net