Re:Former perl, python, java geek gone to Ruby
on
Ruby 1.8.0 Released
·
· Score: 5, Informative
Why can't I define a method that takes two or more blocks (e.g. if/then/else) with the same syntax I use for methods that take a single block? Why can't I introspect the structure of a block? Why the duality with Proc objects? In short, why aren't blocks first class objects?
To clarify this first: It's always possible to create multiple Proc objects with Proc.new, lambda or proc and pass them to a method.
There are two reasons why there are blocks AND Proc objects:
To use a block it's not necessary to create an object and that's good for the performance, e. g. if you have to iterate very often over some collection.
Blocks are used for iterators and control structures, so Matz wanted them to look like those already did.
It would perhaps be possible to have something like that:
foo {... } {... }
But there is an ambiguity because the first block could also be a hash constructor. I am not sure if it would be possible to solve that problem by changing the parser. You could limit yourself to use only do... end with multiple blocks but I thinks that it's better not to have multiple do... end blocks in one method call.
BTW: The if/then/else is not a method call and the selectors consist only of a single word in Ruby unlike in Smalltalk. So it would require a big change to the language and the interpreter if blocks should be used there.
Introspection of blocks is a good idea. Perhaps this will be possible if the new VM for Ruby 2.0, called Rite, is implemented. AFAIK it also should be possible to change code in the parse tree on the fly at arbitrary places then.
More to the point, in ruby I'd like to be able to change the scope or storage class of an object reference without having to rename it.
This is clearly a tradeoff. You can choose between having to look up the variables everytime you want to know their scope or between seeing it easily and change every variable if you want to extract a method. I think to choose the latter is a good choice for a language where you don't usually program in a code browser.
Re:Former perl, python, java geek gone to Ruby
on
Ruby 1.8.0 Released
·
· Score: 3, Informative
> * Blocks are litteraly a bag hung on the side. Needlessly ugly and limiting.
Why do you feel they are ugly? Ok, they are not real functions like scheme has them, but Ruby wants to be an object oriented language, so it's ok that they are (can be transformed to) objects. Ruby is just consistent in not having any functions but only methods, so you have to use Proc#call(x) or Proc#[x] to call a procedure with arguments.
They are real lexical closures, too, which wasn't mentioned in any thread before:
> * The typographic hungarian notation ($ for globals, capitals for constants, etc)
Hungarian notation encodes the type of a variable into the variable name. In Ruby the sigils are used to show the scope of the variables. You can see at one glance that @@foo is class variable, @bar is an instance variable and $baz is a global variable. I found this to be very useful while refactoring code.
> * The premptive binding of literals to built in classes.
In the case of small integers this is more time&space efficient and that's the price you have to pay.
> * The perl compatibility frosting.
There isn't really much left of perl compatibility and lots of perl's "features" are about to be deprecated. In general they aren't used very often by Ruby programmers. It's true that a lot of stuff looks like Perl,/^a.*/ and 1..10 for example, but unlike in Perl these are real objects and first class citizens in Ruby.
> It's still my scripting language of choice though.
Yeah, all scripting languages suck, Ruby just sucks less. *g*
In Ruby there are global variables (starting with $) and constants (first letter is uppercase). The difference is that globals are global for the whole script and can be modified from anywhere.
That way it's easy to redirect STDOUT temporarily: $stdout = File.new("output.txt", "w") puts "output" $stdout = STDOUT
Constants are subject to namespaces (defined by classes and modules):
module A
C = 'A' end
module B
C = 'B' end
A::C # => "A" B::C # => "C"
Like in Smalltalk classes are objects (actually classes are modules and modules are objects), so it's possible to create a class by calling:
klass = Class.new
and then start adding methods to it:
klass.class_eval do
def foo; "foo"; end end
klass.new.foo # => "foo"
class Klass #... end
is essentially syntactic sugar for writing
Klass = Class.new
which assigns a new class to the constant A. You can also assign values to already defined constants (but will have to suffer a warning).
You both seem to confuse things. If you want to create a codeblock you can use
3.times { puts "Ruby rulez!" }
or
3.times do puts "Ruby rulez!" end
It's a question of personal style which you prefer, opinions differ here.
You have to use a begin...end block if you try to catch expceptions.
begin
content = Net::HTTP.get('slashdot.org', '/') rescue SocketError => e
STDERR.puts "Caught: #{e.class} #{e}" ensure
STDOUT.puts "Done." end
If you extract a begin..end block into a separate method later you can just drop the begin and use def..end instead. Ruby is really a pragmatic language it minimizes changes if you refactor your code: it's amazing.
def get_slashdot
Net::HTTP.get('slashdot.org', '/') rescue SocketError => e
STDERR.puts "Caught: #{e.class} #{e}" ensure
STDOUT.puts "Done." end
content = get_slashdot
I have translated a lot of Perl scripts to Ruby and usually they became much shorter and at the same time more readable. (I don't think that was the case because I suck as a perl programmer...;)
This is not exactly true. In the last elections for the German Bundestag I had to to vote with an electronic
voting machine.
For every candidate (1st vote) and party (2nd vote) there was a button on the desk that
had to be pressed. You could also vote "invalid",
that is an option that has to be possible according to the law.
The device is explained in this
article
(sorry, only German).
The article explains
that the voting result is saved into a chip
and also printed on paper. After the election
the votes are counted on the printout and
compared with the results saved into the chip.
If the device is manipulated before the printing
and the saving process that doesn't
really add to the security of the system.
I'd prefer a system with pen and paper and lots
of people that can watch the whole process
directly with their eyes. But the communities seem to go for cheaper elections instead of that.
Re:Sounds like your typical govt agency
on
IT at the CIA
·
· Score: 1
In fact it is much worse. The current US-Administration is practicing "Selective Intelligence - Donald Rumsfeld Has His Own Special Sources. Are They Reliable?".
It follows logically from
Leo Strauss' Philosophy of Deception which
is based on three rules: Deception, Power of Religion and Aggressive Nationalism:
"The people are told what they need to know and no more." While the elite few are capable of absorbing the absence of any moral truth, Strauss thought, the masses could not cope. If exposed to the absence of absolute truth, they would quickly fall into nihilism or anarchy...
Karl Popper has written "The Open Society And Its Enemies" about ideologies of this type in the 1940-ies. He had national socialism and communism in mind, but
he seems to be pretty modern again.
This was said also said in the article. The important point is that Galileo was kind of stalled because some EU member countries couldn't agree on who should build all the required stuff and who should pay for it. I think "recent events" helped to persuade them that the project should be started very soon.
Why can't I define a method that takes two or more blocks (e.g. if/then/else) with the same syntax I use for methods that take a single block? Why can't I introspect the structure of a block? Why the duality with Proc objects? In short, why aren't blocks first class objects?
To clarify this first: It's always possible to create multiple Proc objects with Proc.new, lambda or proc and pass them to a method.
There are two reasons why there are blocks AND Proc objects:
It would perhaps be possible to have something like that:
But there is an ambiguity because the first block could also be a hash constructor. I am not sure if it would be possible to solve that problem by changing the parser. You could limit yourself to use only doBTW: The if/then/else is not a method call and the selectors consist only of a single word in Ruby unlike in Smalltalk. So it would require a big change to the language and the interpreter if blocks should be used there.
Introspection of blocks is a good idea. Perhaps this will be possible if the new VM for Ruby 2.0, called Rite, is implemented. AFAIK it also should be possible to change code in the parse tree on the fly at arbitrary places then.
More to the point, in ruby I'd like to be able to change the scope or storage class of an object reference without having to rename it.
This is clearly a tradeoff. You can choose between having to look up the variables everytime you want to know their scope or between seeing it easily and change every variable if you want to extract a method. I think to choose the latter is a good choice for a language where you don't usually program in a code browser.
> * Blocks are litteraly a bag hung on the side. Needlessly ugly and limiting.
/^a.*/ and 1..10 for example, but unlike in Perl these are real objects and first class citizens in Ruby.
Why do you feel they are ugly? Ok, they are not real functions like scheme has them, but Ruby wants to be an object oriented language, so it's ok that they are (can be transformed to) objects. Ruby is just consistent in not having any functions but only methods, so you have to use Proc#call(x) or Proc#[x] to call a procedure with arguments.
They are real lexical closures, too, which wasn't mentioned in any thread before:
def make_counter
x = 0
lambda do x += 1 end
end
c1, c2 = make_counter, make_counter
c1.call # => 1
c1.call # => 2
c2.call # => 1
c1.call # => 3
c2.call # => 2
> * The typographic hungarian notation ($ for globals, capitals for constants, etc)
Hungarian notation encodes the type of a variable into the variable name. In Ruby the sigils are used to show the scope of the variables. You can see at one glance that @@foo is class variable, @bar is an instance variable and $baz is a global variable. I found this to be very useful while refactoring code.
> * The premptive binding of literals to built in classes.
In the case of small integers this is more time&space efficient and that's the price you have to pay.
> * The perl compatibility frosting.
There isn't really much left of perl compatibility and lots of perl's "features" are about to be deprecated. In general they aren't used very often by Ruby programmers. It's true that a lot of stuff looks like Perl,
> It's still my scripting language of choice though.
Yeah, all scripting languages suck, Ruby just sucks less. *g*
In Ruby there are global variables (starting with $) and constants (first letter is uppercase). The difference is that globals are global for the whole script and can be modified from anywhere.
...
That way it's easy to redirect STDOUT temporarily:
$stdout = File.new("output.txt", "w")
puts "output"
$stdout = STDOUT
Constants are subject to namespaces (defined by classes and modules):
module A
C = 'A'
end
module B
C = 'B'
end
A::C # => "A"
B::C # => "C"
Like in Smalltalk classes are objects (actually classes are modules and modules are objects), so it's possible to create a class by calling:
klass = Class.new
and then start adding methods to it:
klass.class_eval do
def foo; "foo"; end
end
klass.new.foo # => "foo"
class Klass
#
end
is essentially syntactic sugar for writing
Klass = Class.new
which assigns a new class to the constant A. You can also assign values to already defined constants (but will have to suffer a warning).
You both seem to confuse things. If you want to create a codeblock you can use
;)
3.times { puts "Ruby rulez!" }
or
3.times do puts "Ruby rulez!" end
It's a question of personal style which you prefer, opinions differ here.
You have to use a begin...end block if you try to catch expceptions.
begin
content = Net::HTTP.get('slashdot.org', '/')
rescue SocketError => e
STDERR.puts "Caught: #{e.class} #{e}"
ensure
STDOUT.puts "Done."
end
If you extract a begin..end block into a separate method later you can just drop the begin and use def..end instead. Ruby is really a pragmatic language it minimizes changes if you refactor your code: it's amazing.
def get_slashdot
Net::HTTP.get('slashdot.org', '/')
rescue SocketError => e
STDERR.puts "Caught: #{e.class} #{e}"
ensure
STDOUT.puts "Done."
end
content = get_slashdot
I have translated a lot of Perl scripts to Ruby and usually they became much shorter and at the same time more readable. (I don't think that was the case because I suck as a perl programmer...
> For pleasure, in my own time, code in C.
You should have told us, that you are a masochist...
Yeah, it's good to have an alternative to FOX news...
I think it depends on the communities' decision
if you had to use a voting machine. I fear that
this will become more common in the future...
This is not exactly true. In the last elections for the German Bundestag I had to to vote with an electronic voting machine. For every candidate (1st vote) and party (2nd vote) there was a button on the desk that had to be pressed. You could also vote "invalid", that is an option that has to be possible according to the law.
The device is explained in this article (sorry, only German). The article explains that the voting result is saved into a chip and also printed on paper. After the election the votes are counted on the printout and compared with the results saved into the chip. If the device is manipulated before the printing and the saving process that doesn't really add to the security of the system. I'd prefer a system with pen and paper and lots of people that can watch the whole process directly with their eyes. But the communities seem to go for cheaper elections instead of that.
In fact it is much worse. The current US-Administration is practicing "Selective Intelligence - Donald Rumsfeld Has His Own Special Sources. Are They Reliable?".
It follows logically from Leo Strauss' Philosophy of Deception which is based on three rules: Deception, Power of Religion and Aggressive Nationalism:
Karl Popper has written "The Open Society And Its Enemies" about ideologies of this type in the 1940-ies. He had national socialism and communism in mind, but he seems to be pretty modern again.
This was said also said in the article. The important point is that Galileo was kind of stalled
because some EU member countries couldn't agree on who should build all the required stuff and who should pay for it. I think "recent events" helped to persuade them that the project should be started very soon.
perl -p -i -e 'BEGIN { $a = [ "A" .. "Z", "a" .. "z" ]; } $i++ % 11 == 10 and print "# Very important comment: ", map($a->[rand @$a] => 1 .. 50), "\n" ' src/*